Освещение событий window.resize в Internet Explorer

Как вам известно, в Internet Explorer событие window.resize запускается, когда изменяется любой элемент на странице. Не имеет значения, изменяется ли элемент страницы путем назначения/изменения его height или style, просто добавив к нему дочерний элемент или что-то еще, даже если изменение размера элемента не влияет на размеры самого окна просмотра.

В моем приложении это вызывает неприятную рекурсию, поскольку в моем обработчике window.resize я изменяю размер <li> элементы, которые, в свою очередь, перегорают window.resize и т.д. Опять же, это только проблема в IE.

Есть ли способ предотвратить window.resize window.resize в IE в ответ на элементы на странице, размер которой изменяется?

Я также должен упомянуть, что я использую jQuery.

Ответ 1

Я только что обнаружил еще одну проблему, которая может вам помочь.

Я использую jQuery, и у меня есть событие window.resize для вызова функции, которая будет переставлять div, добавленный в тело.

Теперь, когда я устанавливаю свойство LEFT css этого добавленного div, событие window.resize получает триггер для NO GOOD REASON.

Это приводит к бесконечному циклу, запускающему window.resize снова и снова.

Код без исправления:

$(window).resize(function(){
    var onResize = function(){
        //The method which alter some css properties triggers 
        //window.resize again and it ends in an infinite loop
        someMethod();
    }
    window.clearTimeout(resizeTimeout);
    resizeTimeout = window.setTimeout(onResize, 10);
});

Решение:

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

$(window).resize(function(){
    var onResize = function(){
        //The method which alter some css properties triggers 
        //window.resize again and it ends in an infinite loop
        someMethod();
    }

    //New height and width
    var winNewWidth = $(window).width(),
        winNewHeight = $(window).height();

    // compare the new height and width with old one
    if(winWidth!=winNewWidth || winHeight!=winNewHeight){
        window.clearTimeout(resizeTimeout);
        resizeTimeout = window.setTimeout(onResize, 10);
    }
    //Update the width and height
    winWidth = winNewWidth;
    winHeight = winNewHeight;
});

Таким образом, в основном он будет проверять, изменяется ли высота или ширина (что произойдет ТОЛЬКО, когда вы действительно измените размер с помощью окна).

Ответ 2

это имело смысл для меня и, похоже, работает в IE7 и выше:

    //variables to confirm window height and width
    var lastWindowHeight = $(window).height();
    var lastWindowWidth = $(window).width();

    $(window).resize(function() {

        //confirm window was actually resized
        if($(window).height()!=lastWindowHeight || $(window).width()!=lastWindowWidth){

            //set this windows size
            lastWindowHeight = $(window).height();
            lastWindowWidth = $(window).width();

            //call my function
            myfunction();


        }
    });

Ответ 3

Свяжите слушателя с изменением размера с помощью .one(), чтобы он отсоединился после стрельбы. Затем вы можете делать все, что хотите, до тех пор, пока в конце вы переустановите слушателя изменения размера. Я нашел самый простой способ сделать это, поместив прослушиватель resize в анонимную функцию следующим образом:

var resizeListener = function(){
  $(window).one("resize",function(){ //unbinds itself every time it fires

    //resize things

    setTimeout(resizeListener,100); //rebinds itself after 100ms
  });
}
resizeListener();

Вам не требуется техническая поддержка setTimeout, обернутая вокруг resizeListener(), но я бросил ее туда как раз в случае и для некоторого дополнительного дросселирования.

Ответ 4

Я решил его, отменив функцию изменения размера, перестроил страницу и снова привязал функцию изменения размера:

function rebuild() {
   $(window).unbind('resize');
   /* do stuff here */
   $(window).bind('resize',rebuild);
}

$(window).bind('resize',rebuild);

ИЗМЕНИТЬ

Связывание и отмена привязки не подходят для IE8. Хотя Microsoft даже отказалась от IE8, вы можете попробовать это (непроверенный!):

function rebuild(){
   if(!window.resizing) return false;
   window.resizing=true;
   /* do stuff here */
   window.resizing=false;
}

window.resizing=false;
document.body.onresize=rebuild;

Ответ 5

@Ответ AamirAfridi.com решил мою проблему.

Это хорошая идея написать общую функцию для решения таких проблем:

function onWindowResize(callback) {
    var width = $(window).width(),
        height = $(window).height();

    $(window).resize(function() {
        var newWidth = $(window).width(),
            newHeight = $(window).height();

        if (newWidth !== width || newHeight !== height) {
            width = newWidth;
            height = newHeight;
            callback();
        }
    });
}

Используйте его так, и вам больше не нужно беспокоиться о другом поведении в IE:

onWindowResize(function() {
    // do something
});

Ответ 6

Сегодня я столкнулся с этой проблемой и решил включить следующее в мой глобальный файл javascript:

var savedHeight = 0;
var savedWidth = 0;
Event.observe(window, 'resize', function (e) {
    if (window.innerHeight == savedHeight && 
        window.innerWidth == savedWidth) { e.stop(); }
    savedHeight = window.innerHeight;
    savedWidth = window.innerWidth;
});

Для этого требуется прототип.

Ответ 7

Комбинация метода unbind/bind с задержкой вызова. Он работает в Internet Explorer 8 и ниже, предотвращая злую петлю и зависает на версиях 6 и 7.

function resizeViewport()
{
    // Unbind and rebind only for IE < 9
    var isOldIE = document.all && !document.getElementsByClassName;

    if( isOldIE )
        $(window).unbind( 'resize', resizeViewport );

    // ...

    if( isOldIE )
    {
        setTimeout(function(){
            $(window).resize( resizeViewport );
        }, 100);
    }
}

$(window).resize( resizeViewport );

Ответ 8

Вы можете попробовать следующее:

Конструктор:

this.clientWidth = null;
this.clientHeight = null;

Некоторая функция:

var clientWidth = window.innerWidth || document.documentElement.clientWidth; 
var clientHeight = window.innerHeight || document.documentElement.clientHeight;
if (clientWidth != this.clientWidth || clientHeight != this.clientHeight ) {
    this.clientWidth = clientWidth;
    this.clientHeight = clientHeight;

    ... YOUR CODE ...
} 

Для Internet Explorer, Chrome, Firefox, Opera и Safari:

window.innerHeight - the inner height of the browser window
window.innerWidth - the inner width of the browser window

Для Internet Explorer 8, 7, 6, 5:

document.documentElement.clientHeight
document.documentElement.clientWidth
    or
document.body.clientHeight
document.body.clientWidth

Ответ 9

(function ($){
     //if ie8 -> return;
     var lastHeight = 0;
     var lastWidth = 0;
     $(window).resize(function(event){
         if (window.innerHeight == lastHeight && window.innerWidth == lastWidth)
             { event.stopImmediatePropagation(); }
         lastHeight = window.innerHeight;
         lastHeight = window.innerWidth;
     });
})();

делает трюк для меня...

Ответ 10

<pre>



var cont = 0;
var tmRsize = 100;
var lastWindowWidth = $(window).width();
var lastWindowHeight = $(window).height();

/*****redimensionamiento**********/
$(window).resize(function()
{
    if($(window).width() != lastWindowWidth || $(window).height() != lastWindowHeight)
    {
        clearTimeout(this.id);
        this.tiempo = tmRsize;
        this.id = setTimeout(doResize, this.tiempo);
    }
});

function doResize()
{
    lastWindowWidth = $(window).width();
    lastWindowHeight = $(window).height();

    $('#destino_1').html(cont++);
}

Ответ 11

Вот как я разбираюсь в том, что событие resize было запущено элементом или действительно изменило размер окна:

Если событие target.nodeType не существует, это скорее всего окно, так как любой другой элемент на странице будет иметь тип nodeType.

Итак, здесь псевдокод (с использованием jQuery) с добавленной проверкой:

$(window).resize(function(event){
    if ( $(event.target.nodeType).length == 0 ){
        // Anything here is run when the window was resized
        // not executed when an element triggered the resize
    }
});

Ответ 12

Я не смог запустить событие изменения размера, когда элемент был изменен (только в IE8).

Однако что такое target в объекте события, когда вы столкнулись с этой проблемой, не могли бы вы сделать:

$(window).resize(function(e) {
    if( e.target != window ) return;
    // your stuff here
});

Ответ 13

Мой патч:

<!--[if lte IE 7]>
<script type="text/javascript">
  window.onresize = null;       // patch to prevent infinite loop in IE6 and IE7
</script>
<![endif]-->

Ответ 14

Это зависит от того, как содержимое находится в событии изменения размера.

Я понял, что приведенное выше решение решается только тогда, когда страница состоит из статического содержимого, а не динамически отображаемых. В динамическом случае, когда существующее содержимое будет повторно отображаться некоторым событием триггера, например функцией перезагрузки содержимого, нам нужно вместо этого использовать $(document).width() или $(document).height().

Это из-за полосы прокрутки окна. Если на странице есть полоса прокрутки, и основное содержимое будет перерисовано, нажав кнопку "Обновить", полоса прокрутки исчезнет на событии. В этом случае $(window).width() или $(window).height() изменяется путем рендеринга содержимого, а не фактическим размером окна.

http://www.tech-step.net/?p=466

Ответ 15

$(window).resize(function(event)
{
    if (typeof event.target.tagName == 'undefined')
    {
        // ...
    }
});