简体   繁体   English

在 Internet Explorer 中触发 window.resize 事件

[英]window.resize event firing in Internet Explorer

As you are aware, in Internet Explorer, the window.resize event is fired when any element on the page is resized.如您所知,在 Internet Explorer 中,当页面上的任何元素调整大小时都会触发 window.resize 事件。 It does not matter whether the page element is resized through assigning/changing its height or style attribute, by simply adding a child element to it, or whatever -- even though the element resizing does not affect the dimensions of the viewport itself.页面元素是否通过分配/更改其高度或样式属性、通过简单地向其添加子元素或其他任何方式来调整大小都无关紧要——即使元素调整大小不会影响视口本身的尺寸。

In my application, this is causing a nasty recursion, since in my window.resize handler I am resizing some <li> elements, which in turn re-fires window.resize, etc. Again, this is only a problem in IE.在我的应用程序中,这会导致令人讨厌的递归,因为在我的 window.resize 处理程序中,我正在调整一些 <li> 元素的大小,这又会重新触发 window.resize 等。同样,这只是 IE 中的一个问题。

Is there any way to prevent window.resize from firing in IE in response to elements on the page being resized?有什么方法可以防止 window.resize 在响应页面上的元素被调整大小时在 IE 中触发?

I should also mention that I'm using jQuery.我还应该提到我正在使用 jQuery。

I just discovered another problem which might help you.我刚刚发现了另一个可能对你有帮助的问题。

I am using jQuery and I have window.resize event to call a function which will re-position the div appended to the body.我正在使用 jQuery 并且我有 window.resize 事件来调用一个函数,该函数将重新定位附加到正文的 div。

Now when I set the LEFT css property of that appended div, the window.resize event get trigger for NO GOOD REASON.现在,当我设置该附加 div 的 LEFT css 属性时,window.resize 事件会因为没有好的原因而触发。

It results in an infinite loop, triggering the window.resize again and again.它导致无限循环,一次又一次地触发 window.resize。

The code without fix:没有修复的代码:

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

Solution:解决方案:

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

So basically it will check if the height or width is changed (which will happen ONLY when you actually resize with window).所以基本上它会检查高度或宽度是否改变(这只会在你实际调整窗口大小时发生)。

this made sense to me and seems to work in IE7 and above:这对我来说很有意义,并且似乎适用于 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();


        }
    });

Bind your resize listener with .one() so that it unbinds itself after firing.使用.one()绑定您的调整大小侦听器,以便它在触发后自行解除绑定。 Then you can do anything you want, so long as at the end you rebind the resize listener.然后你可以做任何你想做的事情,只要最后你重新绑定调整大小的监听器。 I found the easiest way to do this is by putting the resize listener in an anonymous function like so:我发现最简单的方法是将调整大小的侦听器放在一个匿名函数中,如下所示:

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

    //resize things

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

You don't technically need the setTimeout wrapped around the resizeListener() but I'd threw it in there as a just-in-case and for some extra throttling.从技术上讲,您不需要将setTimeout包裹在resizeListener()周围,​​但我将它放在那里作为以防万一和一些额外的限制。

I solved it by unbinding the resize function, rebuilding the page and then binding the resize function again:我通过取消绑定调整大小函数,重建页面,然后再次绑定调整大小函数来解决它:

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

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

EDIT编辑

Bind and unbind don't go well with IE8.绑定和解除绑定不适用于 IE8。 Though Microsoft even gave up on IE8 you might want to try this (untested!):虽然微软甚至放弃了 IE8,但你可能想试试这个(未经测试!):

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

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

@AamirAfridi.com's answer solved my problem. @AamirAfridi.com 的回答解决了我的问题。

It's a good idea to write a common function to solve such stuff:编写一个通用函数来解决此类问题是个好主意:

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

Use it like this, and you don't have to worry about the different behavior in IE any more:像这样使用它,您就不必再担心 IE 中的不同行为了:

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

A mix of the unbind / bind method with a delayed call. unbind / bind方法与延迟调用的混合。 It works in Internet Explorer 8 and below, preventing evil loop and hangs on versions 6 and 7.它适用于 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 );

You can try this:你可以试试这个:

Constructor:构造函数:

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

Some function:一些功能:

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 ...
} 

For Internet Explorer, Chrome, Firefox, Opera, and Safari:对于 Internet Explorer、Chrome、Firefox、Opera 和 Safari:

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

For Internet Explorer 8, 7, 6, 5:对于 Internet Explorer 8、7、6、5:

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

I ran into this problem today and decided to put the following at the top of my global included javascript file:我今天遇到了这个问题,并决定将以下内容放在我的全局包含的 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;
});

That requires Prototype, by the way.顺便说一下,这需要原型。

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

does the trick for me...对我有用吗...

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

Here's how i deal with finding out if the resize event was fired by an element or by really resizing the window:以下是我如何确定 resize 事件是由元素触发还是通过真正调整窗口大小来处理:

If the event's target.nodeType doesn't exist, it is most likely the window, as any other element on the page would have a nodeType.如果事件的 target.nodeType 不存在,则很可能是窗口,因为页面上的任何其他元素都具有 nodeType。

So here's the pseudo-code (using jQuery) with the added check:所以这是添加了检查的伪代码(使用 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
    }
});

I couldn't get the resize event to fire when an element resized (only tried in IE8 though).当元素调整大小时,我无法触发调整大小事件(尽管仅在 IE8 中尝试过)。

However what is the target on the event object when you're experiencing this issue, could you do:但是,当您遇到此问题时,事件对象的target是什么,您可以这样做:

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

My patch:我的补丁:

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

It is up to the how contents are on the resize event.这取决于 resize 事件中的内容。

I figured out the above solves only when a page consists of static contents, not dynamically rendered ones.我发现只有当页面由静态内容组成时才能解决上述问题,而不是动态呈现的内容。 In the dynamic case where the existing contents will be re-rendered by some trigger event like a contents reload function, we need to use $(document).width() or $(document).height() instead.在现有内容将被某些触发事件(如内容重新加载函数)重新渲染的动态情况下,我们需要使用 $(document).width() 或 $(document).height() 代替。

This is because of scroll bar of the window.这是因为窗口的滚动条。 If a page has the scroll bar and the main contents will be re-rendered by clicking a button “Reload”, the scroll bar disappears on the event.如果页面有滚动条并且主要内容将通过单击“重新加载”按钮重新呈现,则滚动条在事件上消失。 In that case, $(window).width() or $(window).height() is changed by the contents rendering, not by the actual window resizing.在这种情况下, $(window).width() 或 $(window).height() 是由内容呈现改变的,而不是由实际的窗口调整大小改变的。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM