Событие изменения размера окна JavaScript - PullRequest
562 голосов
/ 13 марта 2009

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

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

Ответы [ 12 ]

597 голосов
/ 13 марта 2009

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

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

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

504 голосов
/ 30 июня 2010

Никогда не переопределять функцию 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');
});
485 голосов
/ 30 августа 2013

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

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

Вот рабочий образец .

25 голосов
/ 06 апреля 2017

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

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

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

15 голосов
/ 05 октября 2015

Я верю, что @Alex V уже дал правильный ответ, но ответ требует некоторой модернизации, так как ему уже более пяти лет.

Есть два основных вопроса:

  1. Никогда не используйте object в качестве имени параметра. Это зарезервированное слово. Учитывая это, предоставляемая @Alex V функция не будет работать в strict mode.

  2. Функция 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);
12 голосов
/ 05 декабря 2009

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

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

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

11 голосов
/ 20 марта 2018

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

9 голосов
/ 16 ноября 2009
window.onresize = function() {
    // your code
};
6 голосов
/ 13 марта 2009

Вам может пригодиться следующее сообщение в блоге: Исправление события изменения размера окна в 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);
}
2 голосов
/ 20 апреля 2014

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

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 события resize. Например:

var child1 = document.getElementById("child1");
child1.addEventListener("resize", function (event) {
  ...
  event.preventDefault();
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...