所以我目前使用类似以下的代码:
$(window).resize(function(){resizedw();});
但是这个函数在调整大小过程中会被多次调用。是否有可能在其结束时捕获一个事件?
所以我目前使用类似以下的代码:
$(window).resize(function(){resizedw();});
但是这个函数在调整大小过程中会被多次调用。是否有可能在其结束时捕获一个事件?
setTimeout()
和 clearTimeout()
函数。function resizedw(){
// Haven't resized in 100ms!
}
var doit;
window.onresize = function(){
clearTimeout(doit);
doit = setTimeout(resizedw, 100);
};
在 jsfiddle 上的代码示例。
我遵循以下建议取得了成功:http://forum.jquery.com/topic/the-resizeend-event
下面是代码,这样您就不必再浏览他的帖子链接和源码了:
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');
}
}
感谢sime.vidas提供的代码!
new Date(-1E12)
的形式 - 即JSLint警告不要使用00
。 - elundmarkrtime: Date; .... if (+new Date() - +rtime < delta)
在 TypeScript 中,resizeend 函数应该是箭头函数,像这样 resizeend=()=>
。因为在 resizeend 函数中,this
引用了 window 对象。 - Muhammet Can TONBUL这是我根据 @Mark Coleman 的回答编写的代码:
$(window).resize(function() {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function(){
console.log('Resized finished.');
}, 250);
});
谢谢马克!
resizeTimer
是一个全局变量,这意味着它被定义在window
上,所以它与此处完全相同,只是这个例子更好,因为你不需要在外部定义变量。将此变量添加到window
对象也是有意义的,因为事件监听器绑定到的就是该对象。 - vsyncInternet Explorer 提供了一个 resizeEnd 事件。在你调整大小时,其他浏览器会多次触发 resize 事件。
这里还有其他很好的答案,展示了如何使用 setTimeout 和 lodash、underscore 的 .throttle、.debounce 方法,因此我将提到 Ben Alman 的 throttle-debounce jQuery 插件,它可以实现您想要的功能。
假设您有这个函数,您想在调整大小后触发它:
function onResize() {
console.log("Resize just happened!");
};
节流示例
在下面的示例中,onResize()
函数只会在窗口调整大小期间每250毫秒被调用一次。
$(window).resize( $.throttle( 250, onResize) );
防抖示例
在下面的示例中,onResize()
只会在窗口调整大小操作结束时被调用一次。这实现了与@Mark在他的回答中提出的相同结果。
$(window).resize( $.debounce( 250, onResize) );
使用Underscore.js可以实现一个优雅的解决方案。因此,如果您在项目中使用它,可以采取以下措施-
$( window ).resize( _.debounce( resizedw, 500 ) );
这应该足够了 :) 但是,如果您有兴趣阅读更多相关内容,可以查看我的博客文章 - http://rifatnabi.com/post/detect-end-of-jquery-resize-event-using-underscore-debounce(链接已失效)
lodash
也提供了这个功能。 - vsync有一种更简单的方法,在调整大小结束时执行函数,而不是计算两次调用之间的时间差,只需这样做:
var resizeId;
$(window).resize(function() {
clearTimeout(resizeId);
resizeId = setTimeout(resizedEnded, 500);
});
function resizedEnded(){
...
}
对于Angular2的等效方法:
private resizeId;
@HostListener('window:resize', ['$event'])
onResized(event: Event) {
clearTimeout(this.resizeId);
this.resizeId = setTimeout(() => {
// Your callback method here.
}, 500);
}
对于角度方法,请在setTimeout
中使用() => { }
符号以保留作用域,否则您将无法进行任何函数调用或使用this
。
一种解决方法是使用一个函数扩展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));
});
};
示例用法:
$(window).resized(myHandler, 300);
$(window).resized();
上使用它?因为当我尝试使用多个 $(window).resized();
时,只有最后一个被执行。 - Jandonwindow
中。$(scope).resized(yourHandler, 300)。或者通过实现一种将所有回调保存到数组中并在超时被触发时依次调用它们的方法。 - Jone Polvora您可以将引用 ID 存储到任何 setInterval 或 setTimeout。像这样:
var loop = setInterval(func, 30);
// some time later clear the interval
clearInterval(loop);
为了不使用“全局”变量,你可以在函数本身中添加一个局部变量。例如:
$(window).resize(function() {
clearTimeout(this.id);
this.id = setTimeout(doneResizing, 500);
});
function doneResizing(){
$("body").append("<br/>done!");
}
您可以将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));
});
更新
我编写了一个扩展程序来增强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));
像其他on
或bind
事件处理程序一样使用它,除了你可以作为最后一个传递额外的参数:
$(window).on('resize', function(e) {
console.log(e.type + '-event was 200ms not triggered');
}, 200);
我实现了一个函数,触发用户DOM元素上的两个事件:
代码:
var resizeEventsTrigger = (function () {
function triggerResizeStart($el) {
$el.trigger('resizestart');
isStart = !isStart;
}
function triggerResizeEnd($el) {
clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
$el.trigger('resizeend');
isStart = !isStart;
}, delay);
}
var isStart = true;
var delay = 200;
var timeoutId;
return function ($el) {
isStart ? triggerResizeStart($el) : triggerResizeEnd($el);
};
})();
$("#my").on('resizestart', function () {
console.log('resize start');
});
$("#my").on('resizeend', function () {
console.log('resize end');
});
window.onresize = function () {
resizeEventsTrigger( $("#my") );
};
.one()
,这样它只会在所有调整大小完成后执行,而不是一遍又一遍地执行? - Brad Christie