Событие изменения размера окна JavaScript

Как я могу подключиться к событию изменения размера окна браузера?

Здесь способ jQuery для прослушивания событий изменения размера, но я бы предпочел не включать его в свой проект только для этого требования.

+513
источник поделиться
12 ответов

jQuery просто обертывает стандартное событие resize DOM, например.

window.onresize = function(event) {
    ...
};

jQuery может выполнить некоторую работу, чтобы гарантировать, что событие resize будет запущено последовательно во всех браузерах, но я не уверен, что какой-либо из браузеров отличается, но я бы рекомендовал вам протестировать Firefox, Safari и IE.

+554
источник

Никогда не переопределяйте функцию 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');
});
+483
источник
другие ответы

Связанные вопросы


Похожие вопросы

Во-первых, я знаю, что метод addEventListener упоминался в комментариях выше, но я не видел никакого кода. Поскольку это предпочтительный подход, вот он:

window.addEventListener('resize', function(event){
  // do stuff here
});

Здесь рабочий пример.

+434
источник

Событие изменения размера никогда не должно использоваться напрямую, поскольку оно запускается непрерывно по мере изменения размера.

Используйте функцию 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);

Здесь небольшая библиотека, которую я собрал, чтобы позаботиться об этом аккуратно.

+18
источник

Я верю, что правильный ответ уже был предоставлен @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);
+15
источник

Спасибо за ссылку на мой пост в блоге http://mbccs.blogspot.com/2007/11/fixing-window-resize-event-in-ie.html.

Пока вы можете просто подключиться к стандартным событиям изменения размера окна, вы обнаружите, что в IE событие запускается один раз для каждого X и один раз для каждого перемещения оси Y, в результате чего происходит тонна событий, которые могут оказывают влияние на ваш сайт, если рендеринг является интенсивной задачей.

Мой метод включает короткий тайм-аут, который отменяется при последующих событиях, чтобы событие не попадало в ваш код до тех пор, пока пользователь не закончит изменение размера окна.

+13
источник
window.onresize = function() {
    // your code
};
+10
источник

Следующий пост в блоге может быть вам полезен: Фиксация события изменения размера окна в 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);
}
+6
источник

Решение для 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, но, скорее всего, последуют и другие браузеры (скоро). Пока вы должны использовать полипол.

+6
источник

Вышеупомянутые выше решения будут работать, если все, что вы хотите сделать, это изменить размер окна и окна. Однако, если вы хотите, чтобы изменение размера распространялось на дочерние элементы, вам нужно будет распространять событие самостоятельно. Вот пример кода для этого:

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();
});
+2
источник
<script language="javascript">
    window.onresize = function() {
    document.getElementById('ctl00_ContentPlaceHolder1_Accordion1').style.height = '100%';
} 

</script>
+1
источник
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_];
        }
    }
}
+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос