Internet Explorer中触发window.resize事件


76

如您所知,在Internet Explorer中,调整页面上任何元素的大小时,都会触发window.resize事件。通过分配/更改其height或style属性,仅向其添加子元素或其他内容来调整页面元素的大小都没有关系-即使该元素的大小调整不会影响视口本身的尺寸。

在我的应用程序中,这导致了令人讨厌的递归,因为在window.resize处理程序中,我正在调整某些<li>元素的大小,这些元素又会重新触发window.resize等。同样,这只是IE中的一个问题。

有什么方法可以防止window.resize在IE中触发以响应页面上正在调整大小的元素?

我还应该提到我正在使用jQuery。


2
有趣的是,我不知道。我对JQuery不熟悉,但是如果事件的源元素不是窗口本身,则应该可以停止该事件。我确定有人会提出编码解决方案。
Pekka

这是什么版本的IE,您能否提供一些代码,实际显示调整元素大小会触发window.resize?
DEfusion 2009年


1
对于这个问题,我感激不尽。我一直拔头发:“为什么我的页面这么慢?” 原来,ie8会在每个帧上不断触发window.resize,然后我的大小调整处理程序将不得不一遍
又一

谢谢你 也可以确认这是IE9上的问题。
SAGExSDX 2013年

Answers:


60

我刚刚发现了另一个可能对您有帮助的问题。

我正在使用jQuery,并且我有window.resize事件来调用一个函数,该函数将重新定位附加到主体的div。

现在,当我设置该附加div的LEFT css属性时,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;
});

因此,基本上它将检查高度或宽度是否已更改(仅当您实际调整窗口大小时才会发生)。


亚米尔,看起来就可以了。让我尝试一下,我会再回来告诉您它是如何工作的。
MissingLinq

1
感谢您的想法,以检查窗口的宽度/高度是否已更改,以查看实际窗口是否已调整大小!
布莱恩丹尼

是onResize全局性的,还是您忘记了var?
杰斯罗·拉森

极好的解决方案-具有与此修复程序相同的无限循环情况。
Prembo

尽管检查宽度或高度是否更改仍然是一个好主意,但这并不能解决resize即使宽度和高度保持不变也连续触发处理程序的情况。在我的情况下,它是document导致处理程序触发并导致无限循环的对象。
WynandB 2014年

25

这对我来说很有意义,并且似乎可以在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();


        }
    });

19

与您的调整大小的侦听器绑定在一起.one(),以使其在触发后自动解除绑定。然后,您可以做任何您想做的事情,只要最后您重新绑定了大小调整侦听器。我发现最简单的方法是将调整大小的侦听器放在匿名函数中,如下所示:

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()它,但我只是为了防止其他情况而将其扔在那儿。


3
优秀的解决方案。请记住,函数JavaScript中的完整对象,因此resizeListener可以直接传递给setTimeout()而不是使用字符串literal "resizeListener();"
2013年

感谢您的提示,@ user113215。我根据您的建议更新了代码。
brentonstrine

很棒的方法,无需使用任何额外的变量或if语句
Ergec

@brentonstrine这解决了我$(window).resize()挂在IE8上的问题。奇迹般有效。谢谢!
Sithu 2014年

5

我通过解除绑定大小调整功能,重建页面然后再次绑定大小调整功能来解决此问题:

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

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

编辑

绑定和取消绑定不适用于IE8。尽管微软甚至放弃了IE8,但您可能想尝试一下(未经测试!):

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

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

这似乎是最优雅的解决方案,但不幸的是,这似乎对我没有实际作用。我正在Windows XP的IE 8和OS X 10.9的Chrome 36中进行测试。
新浪

是的,jQuery的绑定和取消绑定与IE8的搭配不太好。我怀疑他们(jQuery)是否会解决此问题,因为自2014年4月8日以来,即使Microsoft不再支持IE8 / XP,…
patrick

1
一种变通方法是在调整大小之前检查函数重建的开始时设置一个全局参数:function rebuild(){if(window.resizing)return false; window.resizing = true; / *在此处进行操作* / window.resizing = false;); =>编辑了可读性答案
patrick

4

@ 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
});

1
最好使用setTimeout来检查使用回调,以确保用户已完成窗口大小调整
Aamir Afridi 2014年

1

我今天遇到了这个问题,决定将以下内容放在我的全局包含的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;
});

顺便说一句,这需要原型。


1

所述的混合unbind/bind方法用延迟呼叫。它可在Internet Explorer 8及更低版本的Internet Explorer中正常工作,防止恶性循环并挂在版本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 );

1

您可以尝试以下方法:

构造函数:

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

0
(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;
     });
})();

为我做戏...


0
<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++);
}


0

这是我如何查找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
    }
});

-1

调整元素大小时,我无法触发resize事件(不过仅在IE8中尝试过)。

但是,target遇到此问题时,事件对象上的内容是什么,可以执行以下操作:

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

2
这是行不通的,因为当元素触发window.resize时,window.resize上的目标始终是window。这就是为什么我开始怀疑它实际上无法完成的原因……
MissingLinq

-1

我的补丁:

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

我永远不建议像这种方式弄乱Windows对象。
Aamir Afridi

-2

内容取决于大小调整事件的方式。

我发现只有当页面包含静态内容而不是动态呈现的内容时,以上方法才可以解决。在动态情况下,现有内容将通过某些触发事件(如内容重载函数)重新呈现,我们需要使用$(document).width()或$(document).height()。

这是因为窗口的滚动条。如果页面上有滚动条,并且单击“重新加载”按钮将重新渲染主要内容,则滚动条在事件中消失。在这种情况下,$(window).width()或$(window).height()会通过内容呈现而不是通过实际调整窗口大小来更改。

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


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

该答案如何增加/改善其他高度评价的答案?仅代码的答案不好。提供说明。
random_user_name 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.