76

如您所知,在 Internet Explorer 中,当页面上的任何元素调整大小时都会触发 window.resize 事件。页面元素是否通过分配/更改其高度或样式属性,通过简单地向其添加子元素或其他方式来调整页面元素的大小并不重要 - 即使元素调整大小不会影响视口本身的尺寸。

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

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

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

4

15 回答 15

60

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

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

现在,当我设置附加 div 的 LEFT css 属性时,window.resize 事件会因没有好的理由而触发。

它会导致无限循环,一次又一次地触发 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;
});

所以基本上它会检查高度或宽度是否改变(只有当你实际调整窗口大小时才会发生这种情况)。

于 2009-12-17T11:55:41.523 回答
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();


        }
    });
于 2012-01-08T11:21:17.090 回答
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()但我将其扔在那里以防万一并进行一些额外的节流。

于 2012-11-08T21:21:07.900 回答
5

我通过解除绑定 resize 函数、重建页面然后再次绑定 resize 函数来解决它:

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;
于 2011-10-31T14:07:49.073 回答
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
});
于 2013-07-26T10:02:17.417 回答
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;
});

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

于 2010-10-07T15:20:00.437 回答
1

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 );
于 2012-08-22T16:07:14.857 回答
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
于 2013-12-02T12:19:37.297 回答
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++);
}

于 2014-10-01T12:18:54.093 回答
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;
     });
})();

对我有用吗...

于 2014-01-23T13:04:15.723 回答
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
    }
});
于 2016-11-30T08:43:45.027 回答
-1

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

但是,target当您遇到此问题时,事件对象上的内容是什么,您可以这样做:

$(window).resize(function(e) {
    if( e.target != window ) return;
    // your stuff here
});
于 2009-12-06T12:53:40.530 回答
-1

我的补丁:

<!--[if lte IE 7]>
<script type="text/javascript">
  window.onresize = null;       // patch to prevent infinite loop in IE6 and IE7
</script>
<![endif]-->
于 2010-11-04T17:36:44.880 回答
-2

这取决于 resize 事件中的内容。

我发现只有当页面包含静态内容而不是动态呈现的内容时,上述解决方案才能解决。在现有内容将被某些触发事件(如内容重新加载功能)重新渲染的动态情况下,我们需要使用 $(document).width() 或 $(document).height() 代替。

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

于 2013-09-29T14:01:05.363 回答
-3
$(window).resize(function(event)
{
    if (typeof event.target.tagName == 'undefined')
    {
        // ...
    }
});
于 2012-03-31T12:00:47.657 回答