Как я могу подключиться к событию изменения размера окна браузера?
Здесь способ jQuery для прослушивания событий изменения размера, но я бы предпочел не включать его в свой проект только для этого требования.
Как я могу подключиться к событию изменения размера окна браузера?
Здесь способ jQuery для прослушивания событий изменения размера, но я бы предпочел не включать его в свой проект только для этого требования.
jQuery просто обертывает стандартное событие resize
DOM, например.
window.onresize = function(event) {
...
};
jQuery может выполнить некоторую работу, чтобы гарантировать, что событие resize будет запущено последовательно во всех браузерах, но я не уверен, что какой-либо из браузеров отличается, но я бы рекомендовал вам протестировать Firefox, Safari и IE.
Никогда не переопределяйте функцию window.onresize.
Вместо этого создайте функцию для добавления прослушивателя событий к объекту или элементу. Это проверяет и отключает слушателей, не работает, затем переопределяет функцию объекта как последнее средство. Это предпочтительный метод, используемый в библиотеках, таких как jQuery.
object
: элемент или объект окна type
: изменение размера, прокрутка (тип события) callback
: ссылка на функцию
var addEvent = function(object, type, callback) {
if (object == null || typeof(object) == 'undefined') return;
if (object.addEventListener) {
object.addEventListener(type, callback, false);
} else if (object.attachEvent) {
object.attachEvent("on" + type, callback);
} else {
object["on"+type] = callback;
}
};
Тогда используйте вот так:
addEvent(window, "resize", function_reference);
или с анонимной функцией:
addEvent(window, "resize", function(event) {
console.log('resized');
});
Во-первых, я знаю, что метод addEventListener
упоминался в комментариях выше, но я не видел никакого кода. Поскольку это предпочтительный подход, вот он:
window.addEventListener('resize', function(event){
// do stuff here
});
Событие изменения размера никогда не должно использоваться напрямую, поскольку оно запускается непрерывно по мере изменения размера.
Используйте функцию debounce для уменьшения избыточных вызовов.
window.addEventListener('resize',debounce(handler, delay, immediate),false);
Здесь происходит общее всплывающее обтекание сети, хотя и ищут более продвинутые, как featuerd в lodash.
const debounce = (func, wait, immediate) => {
var timeout;
return () => {
const context = this, args = arguments;
const later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
Это можно использовать так...
window.addEventListener('resize', debounce(() => console.log('hello'),
200, false), false);
Он никогда не будет срабатывать более одного раза каждые 200 мс.
Для мобильных изменений ориентации используйте:
window.addEventListener('orientationchange', () => console.log('hello'), false);
Здесь небольшая библиотека, которую я собрал, чтобы позаботиться об этом аккуратно.
Я верю, что правильный ответ уже был предоставлен @Alex V, но ответ требует некоторой модернизации, поскольку ей уже более пяти лет.
Существуют две основные проблемы:
Никогда не используйте object
как имя параметра. Это запасное слово. С учетом этого функция @Alex V, которая не будет работать в strict mode
, не будет работать.
Функция addEvent
, предоставляемая @Alex V, не возвращает event object
, если используется метод addEventListener
. Другой параметр должен быть добавлен к функции addEvent
, чтобы это разрешить.
ПРИМЕЧАНИЕ. Новый параметр addEvent
стал необязательным, поэтому переход на эту новую функциональную версию не приведет к нарушению предыдущих вызовов этой функции. Все прежние использования будут поддерживаться.
Вот обновленная функция addEvent
с этими изменениями:
/*
function: addEvent
@param: obj (Object)(Required)
- The object which you wish
to attach your event to.
@param: type (String)(Required)
- The type of event you
wish to establish.
@param: callback (Function)(Required)
- The method you wish
to be called by your
event listener.
@param: eventReturn (Boolean)(Optional)
- Whether you want the
event object returned
to your callback method.
*/
var addEvent = function(obj, type, callback, eventReturn)
{
if(obj == null || typeof obj === 'undefined')
return;
if(obj.addEventListener)
obj.addEventListener(type, callback, eventReturn ? true : false);
else if(obj.attachEvent)
obj.attachEvent("on" + type, callback);
else
obj["on" + type] = callback;
};
Пример вызова новой функции addEvent
:
var watch = function(evt)
{
/*
Older browser versions may return evt.srcElement
Newer browser versions should return evt.currentTarget
*/
var dimensions = {
height: (evt.srcElement || evt.currentTarget).innerHeight,
width: (evt.srcElement || evt.currentTarget).innerWidth
};
};
addEvent(window, 'resize', watch, true);
Спасибо за ссылку на мой пост в блоге http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html.
Пока вы можете просто подключиться к стандартным событиям изменения размера окна, вы обнаружите, что в IE событие запускается один раз для каждого X и один раз для каждого перемещения оси Y, в результате чего происходит тонна событий, которые могут оказывают влияние на ваш сайт, если рендеринг является интенсивной задачей.
Мой метод включает короткий тайм-аут, который отменяется при последующих событиях, чтобы событие не попадало в ваш код до тех пор, пока пользователь не закончит изменение размера окна.
window.onresize = function() {
// your code
};
Следующий пост в блоге может быть вам полезен: Фиксация события изменения размера окна в IE
Он предоставляет этот код:
Sys.Application.add_load(function(sender, args) { $addHandler(window, 'resize', window_resize); }); var resizeTimeoutId; function window_resize(e) { window.clearTimeout(resizeTimeoutId); resizeTimeoutId = window.setTimeout('doResizeCode();', 10); }
Решение для 2018+:
Вы должны использовать ResizeObserver. Это будет собственное решение для браузера, которое имеет гораздо лучшую производительность, чем использование события resize
. Кроме того, он не только поддерживает событие в document
но и произвольные elements
.
var ro = new ResizeObserver( entries => { for (let entry of entries) { const cr = entry.contentRect; console.log('Element:', entry.target); console.log('Element size: ${cr.width}px x ${cr.height}px'); console.log('Element padding: ${cr.top}px ; ${cr.left}px'); } }); // Observe one or multiple elements ro.observe(someElement);
В настоящее время поддерживается только Chrome, но, скорее всего, последуют и другие браузеры (скоро). Пока вы должны использовать полипол.
Вышеупомянутые выше решения будут работать, если все, что вы хотите сделать, это изменить размер окна и окна. Однако, если вы хотите, чтобы изменение размера распространялось на дочерние элементы, вам нужно будет распространять событие самостоятельно. Вот пример кода для этого:
window.addEventListener("resize", function () {
var recResizeElement = function (root) {
Array.prototype.forEach.call(root.childNodes, function (el) {
var resizeEvent = document.createEvent("HTMLEvents");
resizeEvent.initEvent("resize", false, true);
var propagate = el.dispatchEvent(resizeEvent);
if (propagate)
recResizeElement(el);
});
};
recResizeElement(document.body);
});
Обратите внимание, что дочерний элемент может вызвать
event.preventDefault();
для объекта события, который передается как первый Arg события изменения размера. Например:
var child1 = document.getElementById("child1");
child1.addEventListener("resize", function (event) {
...
event.preventDefault();
});
<script language="javascript">
window.onresize = function() {
document.getElementById('ctl00_ContentPlaceHolder1_Accordion1').style.height = '100%';
}
</script>
var EM = new events_managment();
EM.addEvent(window, 'resize', function(win,doc, event_){
console.log('resized');
//EM.removeEvent(win,doc, event_);
});
function events_managment(){
this.events = {};
this.addEvent = function(node, event_, func){
if(node.addEventListener){
if(event_ in this.events){
node.addEventListener(event_, function(){
func(node, event_);
this.events[event_](win_doc, event_);
}, true);
}else{
node.addEventListener(event_, function(){
func(node, event_);
}, true);
}
this.events[event_] = func;
}else if(node.attachEvent){
var ie_event = 'on' + event_;
if(ie_event in this.events){
node.attachEvent(ie_event, function(){
func(node, ie_event);
this.events[ie_event]();
});
}else{
node.attachEvent(ie_event, function(){
func(node, ie_event);
});
}
this.events[ie_event] = func;
}
}
this.removeEvent = function(node, event_){
if(node.removeEventListener){
node.removeEventListener(event_, this.events[event_], true);
this.events[event_] = null;
delete this.events[event_];
}else if(node.detachEvent){
node.detachEvent(event_, this.events[event_]);
this.events[event_] = null;
delete this.events[event_];
}
}
}