我使用JQuery这样:
$(window).resize(function() { ... });
但是,如果用户通过拖动窗口边缘来手动调整浏览器窗口的大小,上面的.resize事件会触发多次。
问题:如何在浏览器窗口调整大小完成后调用函数(使事件只触发一次)?
我使用JQuery这样:
$(window).resize(function() { ... });
但是,如果用户通过拖动窗口边缘来手动调整浏览器窗口的大小,上面的.resize事件会触发多次。
问题:如何在浏览器窗口调整大小完成后调用函数(使事件只触发一次)?
当前回答
非常感谢大卫沃尔什,这里是一个香草版本的下划线debounce。
代码:
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
简单的用法:
var myEfficientFn = debounce(function() {
// All the taxing stuff you do
}, 250);
$(window).on('resize', myEfficientFn);
裁判:http://davidwalsh.name/javascript-debounce-function
其他回答
许多解决方案。我尝试在mouuseevent之后执行事件,所以我在ouse进入窗口后添加了重载:
jQuery(window).resize(function() {
// this. is window
if( this.resizeTO) {
clearTimeout(this.resizeTO)
};
this.resizeTO = setTimeout(function() {
jQuery(window).mouseenter(function() {
if( jQuery(window).width() < 700 && jQuery(window).width() > 400 ){
console.log("mouseenter reloads elements");
// is loading the page
location.reload();
//
}; // just mobile
}); // mouse fired
}, 400); // set Time Ouuut
});
我使用以下函数来延迟重复操作,它将适用于您的情况:
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
用法:
$(window).resize(function() {
delay(function(){
alert('Resize...');
//...
}, 500);
});
传递给它的回调函数,只会在指定的时间量之后执行最后一次调用延迟,否则计时器将被重置,我发现这对于其他目的很有用,如检测用户何时停止输入等…
如果你安装了Underscore.js,你可以:
$(window).resize(_.debounce(function(){
alert("Resized");
},500));
实际上,据我所知,当resize关闭时,您不能准确地执行某些操作,因为您不知道未来用户的操作。但是您可以假设两次调整大小事件之间的时间间隔,因此如果您等待的时间比这个时间稍长,并且没有进行调整大小,则可以调用您的函数。 我们使用setTimeout和它的id来保存或删除它。例如,我们知道两次调整大小事件之间的时间是500ms,因此我们将等待750ms。
var; $(窗口).resize(函数(){ clearTimeout(一个); a = setTimeout(函数(){ //调用函数 }, 750); });
以下是CMS解决方案的修改,可以在代码中的多个地方调用:
var waitForFinalEvent = (function () {
var timers = {};
return function (callback, ms, uniqueId) {
if (!uniqueId) {
uniqueId = "Don't call this twice without a uniqueId";
}
if (timers[uniqueId]) {
clearTimeout (timers[uniqueId]);
}
timers[uniqueId] = setTimeout(callback, ms);
};
})();
用法:
$(window).resize(function () {
waitForFinalEvent(function(){
alert('Resize...');
//...
}, 500, "some unique string");
});
CMS的解决方案是很好的,如果你只调用它一次,但如果你调用它多次,例如,如果你的代码的不同部分设置了单独的回调窗口调整大小,那么它将失败b/c他们共享计时器变量。
通过这种修改,您可以为每个回调提供一个惟一的id,这些惟一id用于将所有超时事件分开。