简体   繁体   中英

window resize event continually fires in ie7

Old Title: setTimeout throttle on window resize event in javascript continually fires in ie7

I have the following script :

jQuery(document).ready(function(){
    throttleTest(); 
});

function throttleTest() {

    var throttleTimer,
        testCount = 1;

    jQuery(window).on({
        "resize": function(){
            clearTimeout(throttleTimer);
            throttleTimer = setTimeout(function() {
                jQuery("ul.testList").prepend("<li>Prepended list item number: " + testCount + "</li>");
                testCount++;
            }, 500);        
        }
    });

};

And the following HTML :

<ul class="testList">
</ul>

Using a setTimeout throttle technique it should only prepend a list item to the testList ul once the user has stopped resizing their browser for 500ms. Basically it only runs the setTimeout code once on every resize of the browser, due to the clearTimeout prior to it being set. This technique allows code to only be fired when needed and not on every resize event, which could be tens of times whenever the user resizes their browser.

This works across all browsers except for ie7. Bizarrely in ie7, the code continues to run and ceases to stop prepending list items to the ul.

I have set up a demo here: http://jsfiddle.net/cQRjp/

Take a look in ie7 and you will see the issue. Does anyone know why this is failing in ie7?

EDIT No:1:

I have stripped down the code so that on a window resize an li element gets prepended to a ul element on the page and then a counter is incremented. That's it.

This has indicated that the problem lies with how ie7 interprets a resize event, nothing to do with the throttle timer. It seems that prepending an li item to the page triggers the resize event in ie7, therefore, the resize is continuously fired. I have setup a new demo here: http://jsfiddle.net/gnKsE/ Warning this link will crash your ie7 browser.

One solution I can think of to this problem is to turn off the resize event immediately after it is triggered, and then setting it back up again after I have ran the code within it. Like so:

jQuery(document).ready(function(){
    functionName(); 
});

function functionName() {

    var throttleTimer,
        testCount = 1;


    function turnOnResize() {
        jQuery(window).on({
            "resize.anyname": function(){
                jQuery(window).off(".anyname");
                jQuery("ul.testList").prepend("<li>Resize event: " + testCount + "</li>");
                testCount++;
                setTimeout(function() {
                    turnOnResize();
                }, 50);
            }
        });
    }
    turnOnResize();

};

Another solution would be to make your resize handler check to see if the width of the window has changed. That way you can ignore resize events that were not caused by the window being resized. See also: window.resize event firing in Internet Explorer

Try something like this:

jQuery(document).ready(function($){
    var lastWindowHeight = window.innerHeight, // Could use $(window).height() but $(window) is expensive
        lastWindowWidth = window.innerWidth,
        testCount = 1;

    // Handles all resize events (which for IE7 includes when _anything_ in the DOM is resized)
    function resizeHandler() {
        if (lastWindowHeight !== window.innerHeight || lastWindowWidth !== window.innerWidth )
            windowResizeHandler.apply(this, arguments);
    }

    // Handles resize events that result from the window changing size
    function windowResizeHandler() {
        lastWindowHeight = window.innerHeight;
        lastWindowWidth = window.innerWidth;
        $("ul.testList").prepend("<li>Resize event: " + testCount + "</li>");
        testCount++;
    }

    $(window).on("resize", resizeHandler);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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