Вы можете обойти это, заменив объект (и, следовательно, связать область):
def foo(a=[]):
a = list(a)
a.append(5)
return a
Ужасно, но он работает.
Существует очень эффективный метод определения того, был ли изменен размер элемента.
http://marcj.github.io/css-element-queries/
Эта библиотека имеет класс ResizeSensor
, который может использоваться для определения размера.
Пример:
new ResizeSensor(jQuery('#divId'), function(){
console.log('content dimension changed');
});
Пожалуйста, не используйте плагин jQuery onresize, , поскольку для проверки изменений используется цикл setTimeout()
. ЭТО НЕВЕРОЯТНО МЕДЛЕННО И НЕ ТОЧНО.
Раскрытие: Я непосредственно связан с этой библиотекой.
var div = document.getElementById('div');
div.addEventListener('resize', (event) => console.log(event.detail));
function checkResize (mutations) {
var el = mutations[0].target;
var w = el.clientWidth;
var h = el.clientHeight;
var isChange = mutations
.map((m) => m.oldValue + '')
.some((prev) => prev.indexOf('width: ' + w + 'px') == -1 || prev.indexOf('height: ' + h + 'px') == -1);
if (!isChange)
return;
var event = new CustomEvent('resize', {detail: {width: w, height: h}});
el.dispatchEvent(event);
}
var observer = new MutationObserver(checkResize);
observer.observe(div, {attributes: true, attributeOldValue: true, attributeFilter: ['style']});
#div {width: 100px; border: 1px solid #bbb; resize: both; overflow: hidden;}
<div id = "div">DIV</div>
Вы должны привязать событие resize
к объекту window
, а не к общему элементу html.
Затем вы можете использовать это:
$(window).resize(function() {
...
});
и в функции обратного вызова вы можете проверить новую ширину вашего div
вызова
$('.a-selector').width();
Итак, ответ на ваш вопрос - нет, вы не можете связать событие resize
с div.
Вы можете использовать iframe
или object
, используя contentWindow
или contentDocument
при изменении размера. Без setInterval
или setTimeout
relative
IFRAME.contentWindow
- onresize
событие <div style="height:50px;background-color:red;position:relative;border:1px solid red">
<iframe style=width:100%;height:100%;position:absolute;border:none;background-color:transparent allowtransparency=true>
</iframe>
This is my div
</div>
Javascript:
$('div').width(100).height(100);
$('div').animate({width:200},2000);
$('object').attr({
type : 'text/html'
})
$('object').on('resize,onresize,load,onload',function(){
console.log('ooooooooonload')
})
$($('iframe')[0].contentWindow).on('resize',function(){
console.log('div changed')
})
JsFiddle: https://jsfiddle.net/qq8p470d/
element-resize-event
IFRAME.contentWindow
недоступен до тех пор, пока событие if onload
не загорится. Кроме того, вы можете добавить стиль visibility:hidden;
, так как iframe может блокировать ввод мыши в элементы, расположенные за ним (по-видимому, «IE» по крайней мере).
– James Wilkins
16 June 2016 в 05:00
display
элемента.
– trusktr
6 August 2016 в 07:05
Это сообщение в блоге помогло мне эффективно обнаруживать изменения размеров элементов DOM.
Взгляните на это http://benalman.com/code/projects/jquery-resize/examples/resize/
Он имеет различные примеры. Попробуйте изменить размер окна и посмотреть, как отрегулированы элементы внутри элементов контейнера.
Пример с js скриптом, чтобы объяснить, как заставить его работать. Взгляните на эту скрипту http://jsfiddle.net/sgsqJ/4/
В том, что событие resize () связано с элементами, имеющими класс «test», а также к объекту window и изменению размера объекта окна $ ('. test'). Вызывается resize ().
, например
$('#test_div').bind('resize', function(){
console.log('resized');
});
$(window).resize(function(){
$('#test_div').resize();
});
В спецификации существует только Window.onResize
, но вы всегда можете использовать IFrame
для создания нового объекта Window
внутри вашего DIV.
Пожалуйста, проверьте этот ответ . Существует новый маленький плагин jquery , портативный и простой в использовании. Вы всегда можете проверить исходный код, чтобы узнать, как это делается.
<!-- (1) include plugin script in a page -->
<script src="/src/jquery-element-onresize.js"></script>
// (2) use the detectResizing plugin to monitor changes to the element's size:
$monitoredElement.detectResizing({ onResize: monitoredElement_onResize });
// (3) write a function to react on changes:
function monitoredElement_onResize() {
// logic here...
}
Новый стандарт для этого - Resize Observer api, доступный в Chrome 64.
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>
Spec: https://wicg.github.io/ResizeObserver
Полиполняет: https://github.com/WICG/ResizeObserver/issues / 3
Firefox Проблема: https://bugzil.la/1272409
Ошибка Safari: http: // wkb .ug / 157743
Текущая поддержка: http://caniuse.com/#feat=resizeobserver
resize
при изменении размеров: ebidel.github.io/demos/dom_resize_events.html
– ebidel
13 February 2018 в 01:47
jQuery(document).ready( function($) {
function resizeMapDIVs() {
// check the parent value...
var size = $('#map').parent().width();
if( $size < 640 ) {
// ...and decrease...
} else {
// ..or increase as necessary
}
}
resizeMapDIVs();
$(window).resize(resizeMapDIVs);
});
Я НЕ рекомендую взломать setTimeout (), поскольку это замедляет производительность! Вместо этого вы можете использовать DOM-мутационные наблюдатели для прослушивания изменения размера Div.
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>
Вот скрипка https://jsfiddle.net/JerryGoyal/uep7nse1/ Попробуйте изменить размер div.
Вы можете дополнительно обернуть свой метод в debounce для повышения эффективности. debounce
будет запускать ваш метод за x миллисекунды вместо того, чтобы запускать каждую миллисекунду DIV.
Я нашел, что эта библиотека работает, когда решение MarcJ не выполнило:
https://github.com/sdecima/javascript-detect-element-resize
Он очень легкий и обнаруживает даже естественные изменения размера через CSS или просто загрузку / рендеринг HTML.
Пример кода (взято из ссылки):
<script type="text/javascript" src="detect-element-resize.js"></script>
<script type="text/javascript">
var resizeElement = document.getElementById('resizeElement'),
resizeCallback = function() {
/* do something */
};
addResizeListener(resizeElement, resizeCallback);
removeResizeListener(resizeElement, resizeCallback);
</script>
Мой плагин jQuery позволяет событию «изменить размер» на всех элементах не только window
.
https://github.com/dustinpoissant/ResizeTriggering
$("#myElement") .resizeTriggering().on("resize", function(e){
// Code to handle resize
});
Я думал, что это невозможно сделать, но потом я подумал об этом, вы можете вручную изменить размер div с помощью стиля = «изменить размер: оба;» чтобы сделать это, вы должны щелкнуть по нему, чтобы добавить функцию onclick, чтобы проверить высоту и ширину элемента, и это сработало. Только с 5 строками чистого javascript (конечно, это может быть еще короче) http://codepen.io/anon/pen/eNyyVN
<div id="box" style="
height:200px;
width:640px;
background-color:#FF0066;
resize: both;
overflow: auto;"
onclick="myFunction()">
<p id="sizeTXT" style="
font-size: 50px;">
WxH
</p>
</div>
<p>This my example demonstrates how to run a resize check on click for resizable div.</p>
<p>Try to resize the box.</p>
<script>
function myFunction() {
var boxheight = document.getElementById('box').offsetHeight;
var boxhwidth = document.getElementById('box').offsetWidth;
var txt = boxhwidth +"x"+boxheight;
document.getElementById("sizeTXT").innerHTML = txt;
}
</script>
ResizeSensor.js - огромная библиотека, но я уменьшаю ее до ЭТО.
Puff:
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);
});
parseInt( getComputedStyle(element) )
– GetFree
7 May 2018 в 18:41
В долгосрочной перспективе вы сможете использовать ResizeObserver .
new ResizeObserver(callback).observe(element);
К сожалению, он не поддерживается по умолчанию во многих браузерах.
В то же время вы можете использовать функцию, как показано ниже. Так как большинство изменений размера элемента происходит из изменения размера окна или из-за изменения чего-либо в DOM. Вы можете прослушивать изменение размера окна с помощью события resize окна, и вы можете прослушивать изменения DOM с помощью MutationObserver .
Вот пример функции, которая будет перезвонит вам, когда размер предоставленного элемента изменится в результате любого из этих событий:
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
});
};
body
, как в этом примере, вы можете смотреть элемент напрямую. Это на самом деле более эффективный и эффективный, чем просмотр всего тела.
– trusktr
6 August 2016 в 06:58
Вы можете попробовать код в следующем фрагменте, он покрывает ваши потребности, используя простой javascript. ( запустите фрагмент кода и нажмите ссылку полной страницы, чтобы вызвать предупреждение о том, что размер div изменяется, если вы хотите его протестировать. ).
Исходя из того факта, что это
setInterval
в 100 миллисекунд, я бы осмелился сказать, что мой компьютер не обнаружил, что он слишком сильно голоден. (0,1% ЦП было использовано как общее для всех открытых вкладок в Chrome в тесте времени.). Но опять же, это только для одного div, если вы хотите сделать это для большого количества элементов, тогда да, это может быть очень жарко.Вы всегда можете использовать событие click для остановки div -resize sniffing в любом случае.
var width = 0; var interval = setInterval(function(){ if(width <= 0){ width = document.getElementById("test_div").clientWidth; } if(document.getElementById("test_div").clientWidth!==width) { alert('resized div'); width = document.getElementById("test_div").clientWidth; } }, 100);
<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>
Вы можете проверить
var width = 0; var interval = setInterval(function(){ if(width <= 0){ width = document.getElementById("test_div").clientWidth; } if(document.getElementById("test_div").clientWidth!==width) { alert('resized div'); width = document.getElementById("test_div").clientWidth; } }, 100);
Обновлено
Fiddle
Только объект window генерирует событие «изменить размер». Единственный способ, которым я знаю делать то, что вы хотите сделать, - запустить таймер интервала, который периодически проверяет размер.
Это довольно точная копия верхнего ответа, но вместо ссылки это просто часть кода, которая важна, переводится как IMO, более читабельная и понятная. Несколько других небольших изменений включают использование cloneNode (), а не помещение html в строку js. Маленький материал, но вы можете копировать и вставлять это как есть, и он будет работать.
Способ, которым он работает, заключается в том, что два невидимых divs заполняют элемент, который вы просматриваете, а затем добавляете триггер в каждом, и установить положение прокрутки, которое приведет к запуску изменения прокрутки, если размер изменится.
Все реальные кредиты идут на Marc J, но если вы просто ищете соответствующий код, вот он:
window.El = {}
El.resizeSensorNode = undefined;
El.initResizeNode = function() {
var fillParent = "display: block; position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;";
var triggerStyle = "position: absolute; left: 0; top: 0; transition: 0s;";
var resizeSensor = El.resizeSensorNode = document.createElement("resizeSensor");
resizeSensor.style = fillParent;
var expandSensor = document.createElement("div");
expandSensor.style = fillParent;
resizeSensor.appendChild(expandSensor);
var trigger = document.createElement("div");
trigger.style = triggerStyle;
expandSensor.appendChild(trigger);
var shrinkSensor = expandSensor.cloneNode(true);
shrinkSensor.firstChild.style = triggerStyle + " width: 200%; height: 200%";
resizeSensor.appendChild(shrinkSensor);
}
El.onSizeChange = function(domNode, fn) {
if (!domNode) return;
if (domNode.resizeListeners) {
domNode.resizeListeners.push(fn);
return;
}
domNode.resizeListeners = [];
domNode.resizeListeners.push(fn);
if(El.resizeSensorNode == undefined)
El.initResizeNode();
domNode.resizeSensor = El.resizeSensorNode.cloneNode(true);
domNode.appendChild(domNode.resizeSensor);
var expand = domNode.resizeSensor.firstChild;
var expandTrigger = expand.firstChild;
var shrink = domNode.resizeSensor.childNodes[1];
var reset = function() {
expandTrigger.style.width = '100000px';
expandTrigger.style.height = '100000px';
expand.scrollLeft = 100000;
expand.scrollTop = 100000;
shrink.scrollLeft = 100000;
shrink.scrollTop = 100000;
};
reset();
var hasChanged, frameRequest, newWidth, newHeight;
var lastWidth = domNode.offsetWidth;
var lastHeight = domNode.offsetHeight;
var onResized = function() {
frameRequest = undefined;
if (!hasChanged) return;
lastWidth = newWidth;
lastHeight = newHeight;
var listeners = domNode.resizeListeners;
for(var i = 0; listeners && i < listeners.length; i++)
listeners[i]();
};
var onScroll = function() {
newWidth = domNode.offsetWidth;
newHeight = domNode.offsetHeight;
hasChanged = newWidth != lastWidth || newHeight != lastHeight;
if (hasChanged && !frameRequest) {
frameRequest = requestAnimationFrame(onResized);
}
reset();
};
expand.addEventListener("scroll", onScroll);
shrink.addEventListener("scroll", onScroll);
}
Лучшим решением было бы использовать так называемые запросы элементов. Тем не менее, они не являются стандартными, спецификации не существует, и единственный вариант - использовать одну из доступных полипол / библиотек, если вы хотите пойти этим путем.
Идея, лежащая в основе запросов элементов, заключается в том, чтобы разрешить определенный контейнер на странице для ответа на пространство, которое ему предоставляется. Это позволит написать компонент один раз, а затем отбросить его в любом месте страницы, в то время как он будет корректировать его содержимое до его текущего размера. Независимо от размера окна. Это первое отличие, которое мы видим между запросами элементов и медиа-запросами. Все надеются, что в какой-то момент будет создана спецификация, которая будет стандартизировать запросы элементов (или то, что достигает той же цели) и сделать их родными, чистыми, простыми и надежными. Большинство людей согласны с тем, что запросы СМИ довольно ограничены и не помогают модульным дизайном и реальной отзывчивостью.
Существует несколько полипол / библиотек, которые решают проблему по-разному (можно назвать обходные решения вместо решений хотя):
Я видел другие решения аналогичных проблем. Обычно они используют таймеры или размер окна / видового экрана под капотом, что не является реальным решением. Более того, я думаю, что в идеале это должно решаться главным образом в CSS, а не в javascript или html.
, используя ответ Bharat Patil, просто верните ложь внутри обратного вызова связывания, чтобы предотвратить максимальную ошибку стека, см. пример ниже:
$('#test_div').bind('resize', function(){
console.log('resized');
return false;
});
Использование Clay.js ( https://github.com/zzarcon/clay ) довольно просто обнаружить изменения размера элемента:
var el = new Clay('.element');
el.on('resize', function(size) {
console.log(size.height, size.width);
});
requestAnimationFrame
vssetTimeout
не имеет значения, эта библиотека не зацикливается i>.requestAnimationFrame
используется только для дебюта / дроссельной частоты вызова ваших обратных вызовов, не выполняет опрос i>. В отличие от этого, MutationObserver теоретически может использоваться для подобного эффекта, но не в старых браузерах. Это выдающийся ум. – Han Seoul-Oh 26 April 2017 в 02:29