Javascript 如何等待“调整大小”事件的“结束”,然后才执行操作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5489946/
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
How to wait for the 'end' of 'resize' event and only then perform an action?
提问by Rella
So I currently use something like:
所以我目前使用类似的东西:
$(window).resize(function(){resizedw();});
But this gets called many times while resizing process goes on. Is it possible to catch an event when it ends?
但是在调整大小的过程中,这会被多次调用。是否可以在事件结束时捕获事件?
采纳答案by Dolan Antenucci
I had luck with the following recommendation: http://forum.jquery.com/topic/the-resizeend-event
我对以下建议很幸运:http: //forum.jquery.com/topic/the-resizeend-event
Here's the code so you don't have to dig through his post's link & source:
这是代码,因此您不必仔细阅读他的帖子链接和来源:
var rtime;
var timeout = false;
var delta = 200;
$(window).resize(function() {
rtime = new Date();
if (timeout === false) {
timeout = true;
setTimeout(resizeend, delta);
}
});
function resizeend() {
if (new Date() - rtime < delta) {
setTimeout(resizeend, delta);
} else {
timeout = false;
alert('Done resizing');
}
}
Thanks sime.vidas for the code!
感谢 sime.vidas 的代码!
回答by Mark Coleman
回答by Roy Shoa
This is the code that I write according to @Mark Coleman answer:
这是我根据@Mark Coleman 的回答编写的代码:
$(window).resize(function() {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function(){
console.log('Resized finished.');
}, 250);
});
Thanks Mark!
谢谢马克!
回答by jessegavin
Internet Explorer provides a resizeEndevent. Other browsers will trigger the resize event many times while you're resizing.
Internet Explorer 提供了一个resizeEnd事件。其他浏览器会在您调整大小时多次触发调整大小事件。
There are other great answers here that show how to use setTimeout and the .throttle, .debouncemethods from lodash and underscore, so I will mention Ben Alman's throttle-debounce jQuery pluginwhich accomplishes what you're after.
这里还有其他很棒的答案,展示了如何使用 setTimeout 和.throttle,.debounce方法来自 lodash 和下划线,所以我会提到 Ben Alman 的油门去抖动 jQuery 插件,它可以完成你所追求的。
Suppose you have this function that you want to trigger after a resize:
假设您有一个要在调整大小后触发的函数:
function onResize() {
console.log("Resize just happened!");
};
Throttle Example
In the following example, onResize()
will only be called once every 250 milliseconds during a window resize.
Throttle 示例
在下面的示例中,onResize()
在窗口大小调整期间将仅每 250 毫秒调用一次。
$(window).resize( $.throttle( 250, onResize) );
Debounce Example
In the following example, onResize()
will only be called once at the end of a window resizing action. This achieves the same result that @Mark presents in his answer.
Debounce 示例
在下面的示例中,onResize()
只会在窗口大小调整操作结束时调用一次。这与@Mark 在他的回答中给出的结果相同。
$(window).resize( $.debounce( 250, onResize) );
回答by Rifat
There is an elegant solution using the Underscore.jsSo, if you are using it in your project you can do the following -
有一个使用Underscore.js的优雅解决方案因此,如果您在项目中使用它,您可以执行以下操作 -
$( window ).resize( _.debounce( resizedw, 500 ) );
This should be enough :) But, If you are interested to read more on that, you can check my blog post - http://rifatnabi.com/post/detect-end-of-jquery-resize-event-using-underscore-debounce(deadlink)
这应该足够了:) 但是,如果您有兴趣阅读更多相关内容,可以查看我的博客文章 - http://rifatnabi.com/post/detect-end-of-jquery-resize-event-using-underscore -去抖动(死链)
回答by Jone Polvora
One solution is extend jQuery with a function, e.g.: resized
一种解决方案是使用函数扩展 jQuery,例如: resized
$.fn.resized = function (callback, timeout) {
$(this).resize(function () {
var $this = $(this);
if ($this.data('resizeTimeout')) {
clearTimeout($this.data('resizeTimeout'));
}
$this.data('resizeTimeout', setTimeout(callback, timeout));
});
};
Sample usage:
示例用法:
$(window).resized(myHandler, 300);
$(window).resized(myHandler, 300);
回答by Xman Classical
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);
To do this without a "global" variable you can add a local variable to the function itself. Ex:
要在没有“全局”变量的情况下执行此操作,您可以向函数本身添加一个局部变量。前任:
$(window).resize(function() {
clearTimeout(this.id);
this.id = setTimeout(doneResizing, 500);
});
function doneResizing(){
$("body").append("<br/>done!");
}
回答by Antoine Thiry
There is a much simpler method to execute a function at the end of the resize than calculate the delta time between two calls, simply do it like this :
在调整大小结束时执行函数的方法比计算两次调用之间的时间差要简单得多,只需这样做:
var resizeId;
$(window).resize(function() {
clearTimeout(resizeId);
resizeId = setTimeout(resizedEnded, 500);
});
function resizedEnded(){
...
}
And the equivalent for Angular2:
相当于Angular2:
private resizeId;
@HostListener('window:resize', ['$event'])
onResized(event: Event) {
clearTimeout(this.resizeId);
this.resizeId = setTimeout(() => {
// Your callback method here.
}, 500);
}
For the angular method, use the () => { }
notation in the setTimeout
to preserve the scope, otherwise you will not be able to make any function calls or use this
.
对于 angular 方法,使用 中的() => { }
符号setTimeout
来保留作用域,否则您将无法进行任何函数调用或使用this
.
回答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 on
or bind
-event handler, except that you can pass an extra parameter as a last:
像任何其他on
或bind
-event 处理程序一样使用它,除了您可以将额外的参数作为最后一个传递:
$(window).on('resize', function(e) {
console.log(e.type + '-event was 200ms not triggered');
}, 200);
回答by Sami A.
This is a modification to Dolan's code above, I've added a feature which checks the window size at the start of the resize and compares it to the size at the end of the resize, if size is either bigger or smaller than the margin (eg. 1000) then it reloads.
这是对上面 Dolan 代码的修改,我添加了一个功能,它在调整大小开始时检查窗口大小,并将其与调整大小结束时的大小进行比较,如果大小大于或小于边距(例如 1000) 然后它重新加载。
var rtime = new Date(1, 1, 2000, 12,00,00);
var timeout = false;
var delta = 200;
var windowsize = $window.width();
var windowsizeInitial = $window.width();
$(window).on('resize',function() {
windowsize = $window.width();
rtime = new Date();
if (timeout === false) {
timeout = true;
setTimeout(resizeend, delta);
}
});
function resizeend() {
if (new Date() - rtime < delta) {
setTimeout(resizeend, delta);
return false;
} else {
if (windowsizeInitial > 1000 && windowsize > 1000 ) {
setTimeout(resizeend, delta);
return false;
}
if (windowsizeInitial < 1001 && windowsize < 1001 ) {
setTimeout(resizeend, delta);
return false;
} else {
timeout = false;
location.reload();
}
}
windowsizeInitial = $window.width();
return false;
}