다음 샘플 HTML을 100 % 너비의 DIV가 있습니다. 일부 요소가 포함되어 있습니다. 창 크기 조정을 수행하는 동안 내부 요소의 위치가 변경되고 div의 크기가 변경 될 수 있습니다. div의 치수 변경 이벤트를 연결할 수 있는지 묻고 있습니까? 어떻게합니까? 현재 콜백 함수를 대상 DIV의 jQuery 크기 조정 이벤트에 바인딩하지만 콘솔 로그가 출력되지 않습니다 (아래 참조).
<html>
<head>
<script type="text/javascript" language="javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script type="text/javascript" language="javascript">
$('#test_div').bind('resize', function(){
console.log('resized');
});
</script>
</head>
<body>
<div id="test_div" style="width: 100%; min-height: 30px; border: 1px dashed pink;">
<input type="button" value="button 1" />
<input type="button" value="button 2" />
<input type="button" value="button 3" />
</div>
</body>
</html>
답변
요소의 크기가 변경되었는지 확인하는 매우 효율적인 방법이 있습니다.
http://marcj.github.io/css-element-queries/
이 라이브러리에는 ResizeSensor
크기 조정 감지에 사용할 수 있는 클래스 가 있습니다.
이벤트 기반 접근 방식을 사용하므로 빠르며 CPU 시간을 낭비하지 않습니다.
예:
new ResizeSensor(jQuery('#divId'), function(){
console.log('content dimension changed');
});
jQuery onresize 플러그인 은 루프에서 setTimeout()
DOM clientHeight
/ clientWidth
속성 을 읽고 변경 사항을 확인 하는 데 사용되므로 사용 하지 마십시오 . 레이아웃 스 래싱을 유발하기 때문에
매우 느리고 부정확 합니다 .
공개 :이 라이브러리와 직접 연결되어 있습니다.
답변
이에 대한 새로운 표준은 Chrome 64에서 사용 가능한 크기 조정 관찰자 API입니다.
function outputsize() {
width.value = textbox.offsetWidth
height.value = textbox.offsetHeight
}
outputsize()
new ResizeObserver(outputsize).observe(textbox)
Width: <output id="width">0</output><br>
Height: <output id="height">0</output><br>
<textarea id="textbox">Resize me</textarea><br>
관찰자 크기 조정
사양 : https://wicg.github.io/ResizeObserver
폴리 필 : https://github.com/WICG/ResizeObserver/issues/3
Firefox 문제 : https://bugzil.la/1272409
사파리 문제 : http://wkb.ug/157743
답변
일반 html 요소가 아닌 객체 에서 resize
이벤트 를 바인딩해야합니다 window
.
그런 다음 이것을 사용할 수 있습니다 :
$(window).resize(function() {
...
});
및 콜백 함수 내에서 당신은 당신의 새로운 폭을 확인하실 수 있습니다 div
호출을
$('.a-selector').width();
따라서 귀하의 질문에 대한 답변은 아니오resize
입니다. 이벤트를 div에 바인딩 할 수 없습니다 .
답변
장기적으로 ResizeObserver 를 사용할 수 있습니다 .
new ResizeObserver(callback).observe(element);
불행히도 현재 많은 브라우저에서 기본적으로 지원되지 않습니다.
그 동안 다음과 같은 기능을 사용할 수 있습니다. 요소 크기 변경의 대부분은 DOM 크기 조정 또는 DOM의 창 크기 변경에서 비롯됩니다. 창의 크기 조정 이벤트 로 창 크기 조정을 청취하고 MutationObserver를 사용하여 DOM 변경 사항을 청취 할 수 있습니다 .
다음은 이벤트 중 하나의 결과로 제공된 요소의 크기가 변경 될 때 다시 호출하는 함수의 예입니다.
var onResize = function(element, callback) {
if (!onResize.watchedElementData) {
// First time we are called, create a list of watched elements
// and hook up the event listeners.
onResize.watchedElementData = [];
var checkForChanges = function() {
onResize.watchedElementData.forEach(function(data) {
if (data.element.offsetWidth !== data.offsetWidth ||
data.element.offsetHeight !== data.offsetHeight) {
data.offsetWidth = data.element.offsetWidth;
data.offsetHeight = data.element.offsetHeight;
data.callback();
}
});
};
// Listen to the window's size changes
window.addEventListener('resize', checkForChanges);
// Listen to changes on the elements in the page that affect layout
var observer = new MutationObserver(checkForChanges);
observer.observe(document.body, {
attributes: true,
childList: true,
characterData: true,
subtree: true
});
}
// Save the element we are watching
onResize.watchedElementData.push({
element: element,
offsetWidth: element.offsetWidth,
offsetHeight: element.offsetHeight,
callback: callback
});
};
답변
ResizeSensor.js 는 거대한 라이브러리의 일부이지만 기능을 THIS로 줄였습니다 .
function ResizeSensor(element, callback)
{
let zIndex = parseInt(getComputedStyle(element));
if(isNaN(zIndex)) { zIndex = 0; };
zIndex--;
let expand = document.createElement('div');
expand.style.position = "absolute";
expand.style.left = "0px";
expand.style.top = "0px";
expand.style.right = "0px";
expand.style.bottom = "0px";
expand.style.overflow = "hidden";
expand.style.zIndex = zIndex;
expand.style.visibility = "hidden";
let expandChild = document.createElement('div');
expandChild.style.position = "absolute";
expandChild.style.left = "0px";
expandChild.style.top = "0px";
expandChild.style.width = "10000000px";
expandChild.style.height = "10000000px";
expand.appendChild(expandChild);
let shrink = document.createElement('div');
shrink.style.position = "absolute";
shrink.style.left = "0px";
shrink.style.top = "0px";
shrink.style.right = "0px";
shrink.style.bottom = "0px";
shrink.style.overflow = "hidden";
shrink.style.zIndex = zIndex;
shrink.style.visibility = "hidden";
let shrinkChild = document.createElement('div');
shrinkChild.style.position = "absolute";
shrinkChild.style.left = "0px";
shrinkChild.style.top = "0px";
shrinkChild.style.width = "200%";
shrinkChild.style.height = "200%";
shrink.appendChild(shrinkChild);
element.appendChild(expand);
element.appendChild(shrink);
function setScroll()
{
expand.scrollLeft = 10000000;
expand.scrollTop = 10000000;
shrink.scrollLeft = 10000000;
shrink.scrollTop = 10000000;
};
setScroll();
let size = element.getBoundingClientRect();
let currentWidth = size.width;
let currentHeight = size.height;
let onScroll = function()
{
let size = element.getBoundingClientRect();
let newWidth = size.width;
let newHeight = size.height;
if(newWidth != currentWidth || newHeight != currentHeight)
{
currentWidth = newWidth;
currentHeight = newHeight;
callback();
}
setScroll();
};
expand.addEventListener('scroll', onScroll);
shrink.addEventListener('scroll', onScroll);
};
사용 방법:
let container = document.querySelector(".container");
new ResizeSensor(container, function()
{
console.log("dimension changed:", container.clientWidth, container.clientHeight);
});
답변
나는 setTimeout()
성능을 늦추기 때문에 해킹을 권장하지 않습니다 ! 대신 Div 크기 변경을 청취하기 위해 DOM 돌연변이 관찰자 를 사용할 수 있습니다.
JS :
var observer = new MutationObserver(function(mutations) {
console.log('size changed!');
});
var target = document.querySelector('.mydiv');
observer.observe(target, {
attributes: true
});
HTML :
<div class='mydiv'>
</div>
여기 바이올린
사업부의 크기를 변경하려고는.
debounce
효율성을 높이기 위해 분석법에 분석법을 추가로 포장 할 수 있습니다 . debounce
DIV 크기를 조정할 때마다 밀리 초마다 트리거하는 대신 x 밀리 초마다 메소드를 트리거합니다.
답변
가장 좋은 해결책은 소위 Element Queries 를 사용하는 것 입니다. 그러나 표준이 아니며 사양이 없으며 유일한 방법은 사용하려는 폴리 필 / 라이브러리 중 하나를 사용하는 것입니다.
요소 쿼리의 기본 개념은 페이지의 특정 컨테이너가 제공된 공간에 응답 할 수 있도록하는 것입니다. 이렇게하면 구성 요소를 한 번 작성한 다음 페이지의 아무 곳에 나 놓을 수 있으며 내용을 현재 크기로 조정할 수 있습니다. 창 크기에 관계없이 이것이 요소 쿼리와 미디어 쿼리 사이의 첫 번째 차이점입니다. 누구나 어떤 시점에서 요소 쿼리 (또는 동일한 목표를 달성하는 것)를 표준화하고 기본, 깨끗하고 단순하며 강력하게 만드는 사양이 만들어지기를 희망합니다. 대부분의 사람들은 미디어 쿼리가 상당히 제한적이며 모듈 식 디자인과 진정한 응답 성을 지원하지 않는다는 데 동의합니다.
여러 가지 방법으로 문제를 해결하는 폴리 필 / 라이브러리가 몇 가지 있습니다 (솔루션 대신 해결 방법이라고도 함).
- CSS 요소 쿼리-https: //github.com/marcj/css-element-queries
- BoomQueries- https: //github.com/BoomTownROI/boomqueries
- eq.js- https: //github.com/Snugug/eq.js
- ElementQuery- https: //github.com/tysonmatanich/elementQuery
- 그리고 여기에 나열하지 않을 몇 가지가 있지만 자유롭게 검색 할 수 있습니다. 현재 사용 가능한 옵션 중 어느 것이 가장 좋은지 말할 수 없습니다. 몇 가지 시도하고 결정해야합니다.
비슷한 문제에 대한 다른 해결책을 제안했습니다. 일반적으로 후드 아래에서 타이머 또는 창 / 뷰포트 크기를 사용하는데 이는 실제 솔루션이 아닙니다. 또한 이상적으로는 JavaScript 또는 html이 아닌 CSS에서 주로 해결해야한다고 생각합니다.