У меня есть следующий пример HTML, есть DIV, который имеет ширину 100%. Он содержит несколько элементов. При выполнении изменения размера окон внутренние элементы могут быть переставлены, и размер div может измениться. Я спрашиваю, возможно ли перехватить событие изменения размера div? и как это сделать? В настоящее время я связываю функцию обратного вызова с событием изменения размера jQuery на целевом DIV, однако консольный журнал не выводится, см. Ниже:
<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>
javascript
jquery
html
Уильям Чой
источник
источник
setInterval
здесь в качестве возможного решения. Вы всегда можете привязатьclearInterval
к нажатию кнопки, чтобы остановить цикл, как только ваша работа будет завершена.Ответы:
Существует очень эффективный метод определения размера элемента.
http://marcj.github.io/css-element-queries/
Эта библиотека имеет класс,
ResizeSensor
который можно использовать для обнаружения изменения размера.Он использует подход, основанный на событиях, поэтому он чертовски быстр и не тратит время процессора.
Пример:
Пожалуйста, не используйте плагин jQuery onresize, так как он используется
setTimeout()
в сочетании с чтением DOMclientHeight
/clientWidth
свойств в цикле для проверки изменений.Это невероятно медленно и неточно, так как вызывает перебивание макета .
Раскрытие: я напрямую связан с этой библиотекой.
источник
requestAnimationFrame
vs неsetTimeout
имеет значения, эта библиотека не работает .requestAnimationFrame
используется только для устранения / уменьшения частоты вызовов ваших обратных вызовов, он не опрашивает . MutationObserver теоретически может быть использован для аналогичного эффекта, но не в старых браузерах, в отличие от этого. Это невероятно умно.Новый стандарт для этого - API Resize Observer, доступный в Chrome 64.
Resize Observer
Spec: https://wicg.github.io/ResizeObserver
Polyfills: https://github.com/WICG/ResizeObserver/issues/3
Firefox Issue: https://bugzil.la/1272409
Safari Issue: http://wkb.ug/157743
Текущая поддержка: http://caniuse.com/#feat=resizeobserver
источник
Вы должны привязать
resize
событие кwindow
объекту, а не к элементу общего HTML.Вы могли бы тогда использовать это:
и в функции обратного вызова вы можете проверить новую ширину вашего
div
вызоваИтак, ответ на ваш вопрос - нет , вы не можете связать
resize
событие с div.источник
В долгосрочной перспективе вы сможете использовать ResizeObserver .
К сожалению, в настоящее время он не поддерживается по умолчанию во многих браузерах.
В то же время, вы можете использовать функцию, как показано ниже. Так как большинство изменений размера элемента будет происходить из изменения размера окна или из-за изменения чего-либо в DOM. Вы можете прослушивать изменение размера окна с помощью события resize окна и прослушивать изменения DOM, используя MutationObserver .
Вот пример функции, которая перезвонит вам, когда размер предоставленного элемента изменится в результате любого из этих событий:
источник
body
как в этом примере, вы можете наблюдать за элементом напрямую. Это на самом деле более эффективно и эффективно, чем наблюдать за всем телом.ResizeSensor.js является частью огромной библиотеки, но я сократил ее функциональность до ЭТОГО :
Как это использовать:
источник
parseInt( getComputedStyle(element) )
Я НЕ рекомендую
setTimeout()
взламывать, поскольку это замедляет работу! Вместо этого вы можете использовать наблюдатели мутации DOM для прослушивания изменения размера Div.JS:
HTML:
Вот скрипка
Попробуйте изменить размер div.
Вы можете дополнительно обернуть свой метод в
debounce
метод, чтобы повысить эффективность.debounce
будет вызывать ваш метод каждые x миллисекунд вместо того, чтобы вызывать каждую миллисекунду при изменении размера DIV.источник
Лучшим решением было бы использовать так называемые элементарные запросы . Тем не менее, они не являются стандартными, никакой спецификации не существует - и единственный вариант - использовать одну из доступных полифильмов / библиотек, если вы хотите пойти по этому пути.
Идея, лежащая в основе запросов элементов, состоит в том, чтобы позволить определенному контейнеру на странице реагировать на предоставленное ему пространство. Это позволит записать компонент один раз, а затем поместить его в любое место на странице, в то время как он будет корректировать его содержимое в соответствии с его текущим размером. Неважно, какой размер окна. Это первое различие, которое мы видим между запросами элементов и медиазапросами. Все надеются, что в какой-то момент будет создана спецификация, которая стандартизирует запросы элементов (или что-то, что достигает той же цели) и сделает их родными, чистыми, простыми и надежными. Большинство людей согласны с тем, что медиа-запросы довольно ограничены и не помогают для модульного дизайна и истинного реагирования.
Существует несколько полифильмов / библиотек, которые решают проблему по-разному (хотя их можно назвать обходными решениями вместо решений):
Я видел другие решения подобных проблем. Обычно они используют таймеры или размер окна / окна просмотра под капотом, что не является реальным решением. Кроме того, я думаю, что в идеале это должно решаться в основном в CSS, а не в javascript или html.
источник
Я нашел эту библиотеку работать, когда решение MarcJ не:
https://github.com/sdecima/javascript-detect-element-resize
Он очень легкий и обнаруживает даже естественные изменения размеров с помощью CSS или просто загрузки / рендеринга HTML.
Пример кода (взят по ссылке):
источник
Взгляните на этот http://benalman.com/code/projects/jquery-resize/examples/resize/
У него есть различные примеры. Попробуйте изменить размер вашего окна и посмотрите, как изменяются элементы внутри элементов контейнера.
Пример с js fiddle, чтобы объяснить, как это работает.
Взгляните на эту скрипку http://jsfiddle.net/sgsqJ/4/
При этом событие resize () привязывается к элементам, имеющим класс «test», а также к объекту окна и при вызове resize объекта окна $ ('. Test'). Resize () вызывается.
например
источник
Вы можете использовать
iframe
илиobject
с помощьюcontentWindow
илиcontentDocument
на изменение размера. БезsetInterval
илиsetTimeout
Шаги:
relative
IFRAME.contentWindow
-onresize
событиеПример HTML:
Javascript:
Пример выполнения
JsFiddle: https://jsfiddle.net/qq8p470d/
Узнать больше:
element-resize-event
источник
IFRAME.contentWindow
недоступно, покаonload
событие не сработает в iframe. Кроме того, вы можете захотеть добавить стильvisibility:hidden;
, так как iframe может блокировать ввод мыши в элементы позади него (по крайней мере, в IE он «плавающий»).display
свойство элемента.Только объект окна генерирует событие «изменить размер». Единственный известный мне способ сделать то, что вы хотите, - запустить интервальный таймер, который периодически проверяет размер.
источник
источник
Как ни удивительно, сколько лет эта проблема, это все еще проблема в большинстве браузеров.
Как уже говорили другие, Chrome 64+ теперь поставляется с Resize Observation изначально, однако спецификация все еще находится в тонкой настройке, и Chrome в настоящее время (по состоянию на 2019-01-29) отстает от последней версии спецификации .
Я видел несколько хороших полизаполнений ResizeObserver в дикой природе, однако, некоторые из них не следуют спецификации, а другие имеют некоторые проблемы с вычислениями.
Я отчаянно нуждался в таком поведении для создания некоторых адаптивных веб-компонентов, которые могли бы использоваться в любом приложении. Чтобы они работали хорошо, им нужно всегда знать свои размеры, поэтому ResizeObservers звучит идеально, и я решил создать полифилл, который бы максимально соответствовал спецификации.
Repo: https://github.com/juggle/resize-observer
Демо: https://codesandbox.io/s/myqzvpmmy9
источник
Используя Clay.js ( https://github.com/zzarcon/clay ), довольно просто обнаружить изменения в размере элемента:
источник
Этот пост в блоге помог мне эффективно определять изменения размеров элементов DOM.
http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/
Как использовать этот код ...
Упакованный код, использованный в примере ...
Примечание: AppConfig - это пространство имен / объект, который я использую для организации многократно используемых функций. Не стесняйтесь искать и заменять имя на что угодно.
источник
Мой плагин jQuery включает событие «изменить размер» для всех элементов, не только для
window
.https://github.com/dustinpoissant/ResizeTriggering
источник
Вы можете попробовать код в следующем фрагменте, он покрывает ваши потребности, используя простой JavaScript. ( запустите фрагмент кода и щелкните ссылку на всю страницу, чтобы активировать оповещение о том, что размер div изменен, если вы хотите проверить его. ).
Вы можете проверить скрипку также
ОБНОВИТЬ
Обновленная скрипка
источник
Это в значительной степени точная копия главного ответа, но вместо ссылки важна только часть кода, переведенная в IMO, более удобочитаемая и понятная. Несколько других небольших изменений включают использование cloneNode (), а не помещение html в строку js. Мелкие вещи, но вы можете скопировать и вставить это как есть, и это будет работать.
Это работает, когда два невидимых элемента div заполняют просматриваемый элемент, а затем помещают триггер в каждый элемент и устанавливают позицию прокрутки, которая приведет к срабатыванию изменения прокрутки при изменении размера.
Вся реальная заслуга принадлежит Marc J, но если вы просто ищете соответствующий код, вот он:
источник
Чистое решение Javascript, но работает, только если размер элемента изменяется с помощью кнопки css resize :
offsetWidth
иoffsetHeight
с сохраненными значениями и, если они отличаются, сделайте то, что хотите, и обновите эти значения.источник
Вот упрощенная версия решения @nkron, применимая к одному элементу (вместо массива элементов в ответе @ nkron сложность мне не нужна).
Слушатель и наблюдатель события могут быть удалены:
источник
источник
используя ответ Bharat Patil, просто верните false в обратном вызове bind, чтобы предотвратить ошибку максимального стека, см. пример ниже:
источник
Это действительно старый вопрос, но я решил опубликовать свое решение по этому вопросу.
Я пытался использовать,
ResizeSensor
так как все, казалось, были в восторге. После реализации, однако, я понял, что под капотом Element Query требуется, чтобы рассматриваемый элемент имел положениеrelative
илиabsolute
применялся к нему, что не сработало для моей ситуации.В итоге я обработал это с помощью Rxjs
interval
вместо прямойsetTimeout
илиrequestAnimationFrame
аналогичной предыдущей реализации.Что приятно в наблюдаемой разновидности интервала, так это то, что вы можете модифицировать поток, однако любой другой наблюдаемый может быть обработан. Для меня базовой реализации было достаточно, но вы могли бы сходить с ума и делать всевозможные слияния и т. Д.
В приведенном ниже примере я отслеживаю изменения ширины внутреннего (зеленого) элемента div. Его ширина установлена на 50%, но максимальная ширина составляет 200 пикселей. Перетаскивание ползунка влияет на ширину обёртки (серого) div. Вы можете видеть, что наблюдаемое срабатывает только при изменении ширины внутреннего div, что происходит, только если ширина внешнего div меньше 400px.
источник
Window.onResize
Существует только в спецификации, но вы всегда можете использовать егоIFrame
для создания новогоWindow
объекта внутри DIV.Пожалуйста, проверьте этот ответ . Есть новый маленький плагин jquery , который является портативным и простым в использовании. Вы всегда можете проверить исходный код, чтобы увидеть, как это делается.
источник
я думал, что это не может быть сделано, но потом я подумал об этом, вы можете вручную изменить размер div с помощью style = "resize: both;" чтобы сделать это, вы должны были щелкнуть по нему, поэтому добавили функцию onclick, чтобы проверить высоту и ширину элемента, и это сработало. Всего 5 строк чистого JavaScript (уверен, что он может быть еще короче) http://codepen.io/anon/pen/eNyyVN
источник