Javascript JQuery:如何仅在完成调整大小后才调用 RESIZE 事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4298612/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 11:49:21  来源:igfitidea点击:

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

javascriptjqueryhtml

提问by nickb

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 event function:

我正在尝试这样做,但遇到了问题。我正在使用 JQuery Resize 事件函数:

$(window).resize(function() {
  ... // how to call only once the browser has FINISHED resizing?
});

However, this function is called continuouslyif the user is manually resizing the browser window. Which means, it might call this function dozens of times in short interval of time.

但是,如果用户手动调整浏览器窗口的大小,则会连续调用此函数。这意味着,它可能会在短时间内调用此函数数十次。

How can I call the resize function only a single time(once the browser window has finished resizing)?

我如何可以调用调整大小功能只是一个时间(一旦浏览器窗口已完成调整大小)?

UPDATE

更新

Also without having to use a global variable.

也不必使用全局变量。

回答by Zevan

Here is an example using thejh's instructions

这是一个使用 thejh 指令的示例

You can store a reference id to any setInterval or setTimeout. Like this:

您可以将引用 ID 存储到任何 setInterval 或 setTimeout。像这样:

var loop = setInterval(func, 30);

// some time later clear the interval
clearInterval(loop);

回答by BGerrissen

Debounce.

去抖

function debouncer( func , timeout ) {
   var timeoutID , timeout = timeout || 200;
   return function () {
      var scope = this , args = arguments;
      clearTimeout( timeoutID );
      timeoutID = setTimeout( function () {
          func.apply( scope , Array.prototype.slice.call( args ) );
      } , timeout );
   }
}


$( window ).resize( debouncer( function ( e ) {
    // do stuff 
} ) );

Note, you can use this method for anything you want to debounce (key events etc).

请注意,您可以将此方法用于您想要去抖动的任何内容(关键事件等)。

Tweak the timeout parameter for optimal desired effect.

调整超时参数以获得最佳预期效果。

回答by yckart

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

您可以使用setTimeout()clearTimeout()结合使用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 extensionto 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

我编写了一个扩展来增强 jQuery 的默认on(& bind)-事件处理程序。如果在给定的时间间隔内未触发事件,它将一个或多个事件的事件处理函数附加到所选元素。如果您只想在延迟后触发回调,例如调整大小事件,或者其他情况,这将非常有用。 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 onor bind-event handler, except that you can pass an extra parameter as a last:

像任何其他onbind-event 处理程序一样使用它,除了您可以将额外的参数作为最后一个传递:

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

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

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

回答by kofifus

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

jsfiddle

回答by Jlis

var lightbox_resize = false;
$(window).resize(function() {
    console.log(true);
    if (lightbox_resize)
        clearTimeout(lightbox_resize);
    lightbox_resize = setTimeout(function() {
        console.log('resize');
    }, 500);
});

回答by tybro0103

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

Underscore.js有几个很好的方法来完成这个任务:throttledebounce. 即使您没有使用 Underscore,也请查看这些函数的来源。下面是一个例子:

var redraw = function() {'redraw logic here'};
var debouncedRedraw = _.debounce(redraw, 750);
$(window).on('resize', debouncedRedraw);

回答by lsblsb

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.

resize-event-listener 捕获所有传入的 resize 调用,为每个调用创建一个超时函数,并将超时标识符与迭代编号一起保存在 -array 中'id-'(可用作数组键)tos

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

每次 timout 触发时,它都会调用fn- 函数,该函数会检查这是否是tos数组中的最后一次超时(fn 函数会删除每个执行的 timout)。如果为 true (= if(len-1 == 0)),则调整大小已完成。

回答by Qiang

jQuery provides an offmethod to remove event handler

jQuery 提供了off一种删除事件处理程序的方法

$(window).resize(function(){
    if(magic == true) {
        $(window).off('resize', arguments.callee);
    }
});