Pull to refresh

Решаем проблему вызова события onresize в ИЕ пока не произошло событие onload

Reading time4 min
Views568
В Internet Explorer есть странная вещь (одна из многих), это вызов события onresize тогда и только тогда, когда документ будет полностью загружен. Данная проблема есть в IE 6, 7, 8. Возникло желание побороть сие безобразие и сделать это довольно прозрачно, дабы можно было вешать обработчики не задумываясь что вызваться они могут гораздо позже, чем ожидалось.

Использую jQuery и его внутренний механизм специальных событий, дабы на время, пока документ загружается, можно было использовать альтернативу onresize, а после все вернуть на свои места.

Дабы не описывать механизм специальных событий приложу ссылку

а теперь собственно код:

(function($, resize){
  if ($.browser.msie) {
    var

// Boolean пометка, загружен ли документ или нет
      documentIsLoaded,

/*
* Сохраняем в переменную экземляр jQuery элемента window
* Пользуясь случаем сразу добавляем обработчик onload
*/
      $window = $(window).one("load", function(){
// Если документ загружен, то устанавливаем значение 1 (true)
        documentIsLoaded = 1;
      });

// Возвращает назначение обработчиков onresize в исходное состояние
    function backToNative () {
      $.event.special[resize] = undefined;
      var events = $window.data("events"),
// Сохраняем структуру обработчиков, если таковые есть.
        eventStack = events && events[resize];
// Если есть обработчики событий, то убираем из кэша событий.
      if (eventStack) {
        events[resize] = undefined;
      }
// Назначаем одинарный обработчик onresize, дабы последующие события были делегированы с помощью нативный методов addEventListener/attachEvent
      $window.one(resize, $.noop);
// Если есть сохраненные обработчики, то возвращаем их на место.
      if (eventStack) {
        events[resize] = eventStack;
      }
    }
    
// Добавляем special событие в jQuery
    $.event.special[resize] = {
      setup: function () {
        if (documentIsLoaded) {
          backToNative();
// Возвращаем false чтобы событие было стандартными средствами для данного события
          return !documentIsLoaded;
        }
        var
// Идентификатор setInterval запущенной проверки размеров окна
          checking,
// Определяем текущую ширину окна
          prevWidth = $window.width(),
// Определяем текущую высоту окна
          prevHeight = $window.height();
          
// Собственно сама функция проверки
        (function handler (){
          if (documentIsLoaded) {
            window.clearInterval(checking);
            backToNative();
            return;
          }

          var
            width = $window.width(),
            height = $window.height();

/*
* Проверяем изменились ли размеры окна
* Если изменили, то вызываем хэндлеры по событию
*/
          if (width != prevWidth || height != prevHeight) {
            prevWidth = width;
            prevHeight = height;
            $window.trigger(resize);
          }

// Если проверка не запущена, то запускаем
          if (!checking) {
            checking = window.setInterval(handler, 100);
          }
        })();
      },
      teardowm: $.noop
    };
  }
})(jQuery, "resize");


* This source code was highlighted with Source Code Highlighter.


А теперь можно спокойно назначать обработчики как до загрузки документа, так и после.
var count1 = 1;
jQuery(window).resize(function(){
  alert(count1++);
});
var count2 = 10;
jQuery(window).bind("resize", function(){
  alert((count2 += 10));
});


* This source code was highlighted with Source Code Highlighter.


ПыСы Используемая версия jQuery 1.4.2
ПыСыСы в jQuery 1.4.2 данный фикс не работает т.к. в новой версии изменена система делегирования событий. В Ближайшее время будет выложен совместимый фикс с более новой версией.

UPD onresize для элементов
$(«div»).resize(function(){
  console.log(«width: » + $(this).width() + ", height: " + $(this).height() + ");
});

https://code.google.com/p/jresizeevent/

Tags:
Hubs:
+5
Comments0

Articles

Change theme settings