JQuery: How to call RESIZE event only once it's FINISHED resizing?

后端 未结 8 1155
一向
一向 2020-11-22 07:29

How do I call a function once the browser windows has FINISHED resizing?

I\'m trying to do it like so, but am having problems. I\'m using the JQuery Resize

相关标签:
8条回答
  • 2020-11-22 07:58

    This is my approach:

    document.addEventListener('DOMContentLoaded', function(){
        var tos = {};
        var idi = 0;
        var fn  = function(id)
        {
            var len = Object.keys(tos).length;
    
            if(len == 0)
                return;
    
            to = tos[id];
            delete tos[id];
    
            if(len-1 == 0)
                console.log('Resize finished trigger');
        };
    
        window.addEventListener('resize', function(){
            idi++;
            var id = 'id-'+idi;
            tos[id] = window.setTimeout(function(){fn(id)}, 500);
        });
    });
    

    The resize-event-listener catches all incoming resize calls, creates a timeout-function for each and saves the timeout-identifier along with an iterating number prepended by 'id-' (to be usable as array key) in the tos-array.

    each time, the timout triggers, it calls the fn-function, that checks, if that was the last timeout in the tos array (the fn-function deletes every executed timout). if true (= if(len-1 == 0)), the resizing is finished.

    0 讨论(0)
  • 2020-11-22 08:05

    Underscore.js has a couple of great methods for this task: throttle and debounce. Even if you're not using Underscore, take a look at the source of these functions. Here's an example:

    var redraw = function() {'redraw logic here'};
    var debouncedRedraw = _.debounce(redraw, 750);
    $(window).on('resize', debouncedRedraw);
    
    0 讨论(0)
  • 2020-11-22 08:05

    jQuery provides an off method to remove event handler

    $(window).resize(function(){
        if(magic == true) {
            $(window).off('resize', arguments.callee);
        }
    });
    
    0 讨论(0)
  • 2020-11-22 08:06

    Just to add to the above, it is common to get unwanted resize events because of scroll bars popping in and out, here is some code to avoid that:

    function registerResize(f) {
        $(window).resize(function() {
            clearTimeout(this.resizeTimeout);
            this.resizeTimeout = setTimeout(function() {
                var oldOverflow = document.body.style.overflow;
                document.body.style.overflow = "hidden";
                var currHeight = $(window).height(),
                    currWidth = $(window).width();
                document.body.style.overflow = oldOverflow;
    
                var prevUndefined = (typeof this.prevHeight === 'undefined' || typeof this.prevWidth === 'undefined');
                if (prevUndefined || this.prevHeight !== currHeight || this.prevWidth !== currWidth) {
                    //console.log('Window size ' + (prevUndefined ? '' : this.prevHeight + "," + this.prevWidth) + " -> " + currHeight + "," + currWidth);
                    this.prevHeight = currHeight;
                    this.prevWidth = currWidth;
    
                    f(currHeight, currWidth);
                }
            }, 200);
        });
        $(window).resize(); // initialize
    }
    
    registerResize(function(height, width) {
        // this will be called only once per resize regardless of scrollbars changes
    });
    

    see jsfiddle

    0 讨论(0)
  • 2020-11-22 08:08

    You can use setTimeout() and clearTimeout() in conjunction with jQuery.data:

    $(window).resize(function() {
        clearTimeout($.data(this, 'resizeTimer'));
        $.data(this, 'resizeTimer', setTimeout(function() {
            //do something
            alert("Haven't resized in 200ms!");
        }, 200));
    });
    

    Update

    I wrote an extension to enhance jQuery's default on (& bind)-event-handler. It attaches an event handler function for one or more events to the selected elements if the event was not triggered for a given interval. This is useful if you want to fire a callback only after a delay, like the resize event, or else. https://github.com/yckart/jquery.unevent.js

    ;(function ($) {
        var methods = { on: $.fn.on, bind: $.fn.bind };
        $.each(methods, function(k){
            $.fn[k] = function () {
                var args = [].slice.call(arguments),
                    delay = args.pop(),
                    fn = args.pop(),
                    timer;
    
                args.push(function () {
                    var self = this,
                        arg = arguments;
                    clearTimeout(timer);
                    timer = setTimeout(function(){
                        fn.apply(self, [].slice.call(arg));
                    }, delay);
                });
    
                return methods[k].apply(this, isNaN(delay) ? arguments : args);
            };
        });
    }(jQuery));
    

    Use it like any other on or bind-event handler, except that you can pass an extra parameter as a last:

    $(window).on('resize', function(e) {
        console.log(e.type + '-event was 200ms not triggered');
    }, 200);
    

    http://jsfiddle.net/ARTsinn/EqqHx/

    0 讨论(0)
  • var lightbox_resize = false;
    $(window).resize(function() {
        console.log(true);
        if (lightbox_resize)
            clearTimeout(lightbox_resize);
        lightbox_resize = setTimeout(function() {
            console.log('resize');
        }, 500);
    });
    
    0 讨论(0)
提交回复
热议问题