В jQuery есть resize()
событие -, но он работает только с окном.
jQuery(window).resize(function() { /* What ever */ });
Это прекрасно работает! Но когда я хочу добавить событие в элемент div, это не работает.
Например
jQuery('div').resize(function() { /* What ever */ });
Я хочу запустить обратный вызов, когда размер div-элемента изменился. Я не хочу запускать событие с изменяемым размером - просто событие, чтобы проверить, изменился ли размер элемента div.
Есть какое-нибудь решение для этого?
javascript
jquery
TJR
источник
источник
Ответы:
DIV
не запускаетresize
событие, поэтому вы не сможете делать именно то, что закодировали, но вы можете изучить мониторинг свойств DOM .Если вы на самом деле работаете с чем-то вроде изменения размера, и это единственный способ для div изменить размер, то ваш плагин изменения размера, вероятно, будет реализовывать собственный обратный вызов.
источник
Меня интересовал только триггер при изменении ширины элемента (меня не волнует высота), поэтому я создал событие jquery, которое делает именно это, используя невидимый элемент iframe.
$.event.special.widthChanged = { remove: function() { $(this).children('iframe.width-changed').remove(); }, add: function () { var elm = $(this); var iframe = elm.children('iframe.width-changed'); if (!iframe.length) { iframe = $('<iframe/>').addClass('width-changed').prependTo(this); } var oldWidth = elm.width(); function elmResized() { var width = elm.width(); if (oldWidth != width) { elm.trigger('widthChanged', [width, oldWidth]); oldWidth = width; } } var timer = 0; var ielm = iframe[0]; (ielm.contentWindow || ielm).onresize = function() { clearTimeout(timer); timer = setTimeout(elmResized, 20); }; } }
Для этого требуется следующий css:
iframe.width-changed { width: 100%; display: block; border: 0; height: 0; margin: 0; }
Вы можете увидеть это в действии здесь widthChanged fiddle
источник
var ss = document.createElement('style'); ss.type = "text/css"; ss.innerHTML = "iframe.width-changed {width: 100%;display: block;border: 0;height: 0;margin: 0;}"; document.body.appendChild(ss);
// this is a Jquery plugin function that fires an event when the size of an element is changed // usage: $().sizeChanged(function(){}) (function ($) { $.fn.sizeChanged = function (handleFunction) { var element = this; var lastWidth = element.width(); var lastHeight = element.height(); setInterval(function () { if (lastWidth === element.width()&&lastHeight === element.height()) return; if (typeof (handleFunction) == 'function') { handleFunction({ width: lastWidth, height: lastHeight }, { width: element.width(), height: element.height() }); lastWidth = element.width(); lastHeight = element.height(); } }, 100); return element; }; }(jQuery));
источник
Я создал плагин jquery jquery.resize, он использует resizeObserver, если поддерживается, или решение, основанное на событии прокрутки marcj / css-element-query , без setTimeout / setInterval.
Вы используете только
jQuery('div').on('resize', function() { /* What ever */ });
или как плагин изменения размера
jQuery('div').resizer(function() { /* What ever */ });
Я создал это для jQuery Terminal и извлек в отдельные пакеты репо и npm, но в то же время я переключился на скрытый iframe, потому что у меня были проблемы с изменением размера, если элемент находился внутри iframe. Я могу соответствующим образом обновить плагин. Вы можете посмотреть плагин изменения размера на основе iframe в исходном коде jQuery Terminal .
РЕДАКТИРОВАТЬ : новая версия использует iframe и изменяет размер объекта окна, потому что предыдущие решения не работали, когда страница находилась внутри iframe.
EDIT2 : поскольку резервный вариант использует iframe, вы не можете использовать его с элементами управления формы или изображениями, вам необходимо добавить его в элемент оболочки.
EDIT3:: есть лучшее решение с использованием полифилла resizeObserver, который использует наблюдатель мутаций (если resizeObserver не поддерживается) и работает даже в IE. Он также имеет типизацию TypeScript.
источник
что насчет этого:
divH = divW = 0; jQuery(document).ready(function(){ divW = jQuery("div").width(); divH = jQuery("div").height(); }); function checkResize(){ var w = jQuery("div").width(); var h = jQuery("div").height(); if (w != divW || h != divH) { /*what ever*/ divH = h; divW = w; } } jQuery(window).resize(checkResize); var timer = setInterval(checkResize, 1000);
Кстати, я предлагаю вам добавить идентификатор в div и изменить $ ("div") на $ ("# yourid"), это будет быстрее и не сломается, когда позже вы добавите другие div
источник
resize
запускается событие окна . Вполне возможно, что размер div изменится без немедленного изменения размера окна, и в этом случае/* what ever */
часть не будет оцениваться.$(window).resize
слушает процесс физического изменения размера окна браузера, например, перетаскивая его за правый нижний угол. Нет никаких событий DOM, которые бы запускали это событиеoverflow:hidden
или нет. Этот ответ не решает вашу проблему. Было бы больше смысла запускать этот код в таймере, чем подключать к случайному прослушивателю событий, который, вероятно, никогда не будет запущен. Было бы еще лучше, если бы вы могли использовать мониторинг свойств DOM и вернуться к таймеру (или вручную вызвать какое-то событие в местах, где размер div может измениться).В этом году был выпущен действительно хороший, простой в использовании, легкий (для обнаружения используются собственные события браузера) плагин как для базового JavaScript, так и для jQuery. Он отлично работает:
https://github.com/sdecima/javascript-detect-element-resize
источник
Поддерживается только окно, да, но вы можете использовать для него плагин: http://benalman.com/projects/jquery-resize-plugin/
источник
Для интеграции с картами Google я искал способ определить, когда размер div изменился. Поскольку карты Google всегда требуют правильных размеров, например ширины и высоты, для правильной визуализации.
Решение, которое я придумал, - это делегирование события, в моем случае щелчок по вкладке. Конечно, это может быть изменение размера окна, идея осталась прежней:
if (parent.is(':visible')) { w = parent.outerWidth(false); h = w * mapRatio /*9/16*/; this.map.css({ width: w, height: h }); } else { this.map.closest('.tab').one('click', function() { this.activate(); }.bind(this)); }
this.map
в данном случае это моя карта div. Поскольку мой родитель невидим при загрузке, вычисленные ширина и высота равны 0 или не совпадают. Используя,.bind(this)
я могу делегировать выполнение скрипта (this.activate
) событию (click
).Теперь я уверен, что то же самое относится и к событиям изменения размера.
$(window).one('resize', function() { this.div.css({ /*whatever*/ }); }.bind(this));
Надеюсь, это поможет кому-нибудь!
источник
Просто попробуйте эту функцию (она может работать не только для div):
function resized(elem, func = function(){}, args = []){ elem = jQuery(elem); func = func.bind(elem); var h = -1, w = -1; setInterval(function(){ if (elem.height() != h || elem.width() != w){ h = elem.height(); w = elem.width(); func.apply(null, args); } }, 100); }
Вы можете использовать это так
resized(/*element*/ '.advs-columns-main > div > div', /*callback*/ function(a){ console.log(a); console.log(this); //for accessing the jQuery element you passed }, /*callback arguments in array*/ ['I\'m the first arg named "a"!']);
ОБНОВЛЕНИЕ: вы также можете использовать более прогрессивный наблюдатель (он может работать для любых объектов, а не только для элементов DOM):
function changed(elem, propsToBeChanged, func = function(){}, args = [], interval = 100){ func = func.bind(elem); var currentVal = {call: {}, std: {}}; $.each(propsToBeChanged, (property, needCall)=>{ needCall = needCall ? 'call' : 'std'; currentVal[needCall][property] = new Boolean(); // is a minimal and unique value, its equivalent comparsion with each other will always return false }); setInterval(function(){ $.each(propsToBeChanged, (property, needCall)=>{ try{ var currVal = needCall ? elem[property]() : elem[property]; } catch (e){ // elem[property] is not a function anymore var currVal = elem[property]; needCall = false; propsToBeChanged[property] = false; } needCall = needCall ? 'call' : 'std'; if (currVal !== currentVal[needCall][property]){ currentVal[needCall][property] = currVal; func.apply(null, args); } }); }, interval); }
Просто попробуйте:
var b = '2', a = {foo: 'bar', ext: ()=>{return b}}; changed(a, { // prop name || do eval like a function? foo: false, ext: true }, ()=>{console.log('changed')})
Он будет регистрировать «изменено» каждый раз, когда вы напрямую меняете b, a.foo или a.ext.
источник
setInterval
может стать довольно дорогим, так как он продолжает попытки изменить размерconsole.log
раз перед тем$.each
, вы увидите , что печать каждый100ms
, как вы установите вinterval
setInterval
работает. Это как «живое» письмо - постоянно пингует сервер. Я знаю это. И что? Спектакль? Прочтите мой комментарий выше. Беспокоитесь о чем-нибудь еще? Напиши мне, друг мой.Вы можете изменить текст, контент или атрибут в зависимости от размера экрана: HTML:
<p class="change">Frequently Asked Questions (FAQ)</p> <p class="change">Frequently Asked Questions </p>
Javascript:
<script> const changeText = document.querySelector('.change'); function resize() { if((window.innerWidth<500)&&(changeText.textContent="Frequently Asked Questions (FAQ)")){ changeText.textContent="FAQ"; } else { changeText.textContent="Frequently Asked Questions (FAQ)"; } } window.onresize = resize; </script>
источник
Если вы просто хотите изменить размер самого div, вам нужно указать это в стиле css. Вам нужно добавить свойство переполнения и изменения размера .
Ниже мой фрагмент кода
#div1 { width: 90%; height: 350px; padding: 10px; border: 1px solid #aaaaaa; overflow: auto; resize: both; } <div id="div1"> </div>
источник