在jQuery中限制事件调用
Throttle event calls in jQuery
我有一个keyup
事件绑定到一个函数,大约需要四分之一秒才能完成。
$("#search").keyup(function() {
//code that takes a little bit to complete
});
当用户键入一个完整的单词或快速按下键时,该函数将被连续调用几次,并且需要一段时间才能全部完成。
是否有一种方法来限制事件调用,以便如果有几个快速连续,它只触发最近调用的那个?
看看jQuery Debounce。
$('#search').keyup($.debounce(function() {
// Will only execute 300ms after the last keypress.
}, 300));
这是一个不需要插件的潜在解决方案。使用布尔值来决定是否执行keyup回调,或者跳过它。
var doingKeyup = false;
$('input').keyup(function(){
if(!doingKeyup){
doingKeyup=true;
// slow process happens here
doingKeyup=false;
}
});
您也可以使用优秀的Underscore/_库。
在Josh的回答中,目前最受欢迎的评论是,你是否应该真的限制调用,或者如果你想要一个debouncer。区别有点微妙,但下划线同时具有:_.debounce(function, wait, [immediate])
和_.throttle(function, wait, [options])
。
如果你还没有使用下划线,检查一下。它可以使你的JavaScript更干净,并且足够轻量,让大多数讨厌库的人停下来。
这是使用JQuery的一种干净的方法。
/* delayed onchange while typing jquery for text boxes widget
usage:
$("#SearchCriteria").delayedChange(function () {
DoMyAjaxSearch();
});
*/
(function ($) {
$.fn.delayedChange = function (options) {
var timer;
var o;
if (jQuery.isFunction(options)) {
o = { onChange: options };
}
else
o = options;
o = $.extend({}, $.fn.delayedChange.defaultOptions, o);
return this.each(function () {
var element = $(this);
element.keyup(function () {
clearTimeout(timer);
timer = setTimeout(function () {
var newVal = element.val();
newVal = $.trim(newVal);
if (element.delayedChange.oldVal != newVal) {
element.delayedChange.oldVal = newVal;
o.onChange.call(this);
}
}, o.delay);
});
});
};
$.fn.delayedChange.defaultOptions = {
delay: 1000,
onChange: function () { }
}
$.fn.delayedChange.oldVal = "";
})(jQuery);
节流方法的两个小型通用实现。(我更喜欢通过这些简单的函数来完成,而不是添加另一个jquery插件)
-
在最后一次呼叫后等待一段时间
这个在我们不想调用搜索函数时很有用例如当用户一直输入查询
function throttle(time, func) {
if (!time || typeof time !== "number" || time < 0) {
return func;
}
var throttleTimer = 0;
return function() {
var args = arguments;
clearTimeout(throttleTimer);
throttleTimer = setTimeout(function() {
func.apply(null, args);
}, time);
}
}
调用给定函数的次数不超过给定的时间
下面的命令用于刷新日志
function throttleInterval(time, func) {
if (!time || typeof time !== "number" || time < 0) {
return func;
}
var throttleTimer = null;
var lastState = null;
var eventCounter = 0;
var args = [];
return function() {
args = arguments;
eventCounter++;
if (!throttleTimer) {
throttleTimer = setInterval(function() {
if (eventCounter == lastState) {
clearInterval(throttleTimer);
throttleTimer = null;
return;
}
lastState = eventCounter;
func.apply(null, args);
}, time);
}
}
}
用法很简单:
下一个在inputBox中最后一次击键后等待2s,然后调用应该被节流的函数。
$("#inputBox").on("input", throttle(2000, function(evt) {
myFunctionToThrottle(evt);
}));
下面是一个可以同时测试两者的例子:点击(CodePen)
我在审查zurb-foundation的更改时遇到了这个问题。他们还添加了自己的解封和节流方法。这看起来可能和他在回答中提到的jquery-debounce @josh3736是一样的。
来自他们的网站:
// Debounced button click handler
$('.button').on('click', Foundation.utils.debounce(function(e){
// Handle Click
}, 300, true));
// Throttled resize function
$(document).on('resize', Foundation.utils.throttle(function(e){
// Do responsive stuff
}, 300));
对于一个快速解决方案(注意coffeescript),像这样的东西似乎是最简单的(没有外部库):
running = false
$(document).on 'keyup', '.some-class', (e) ->
return if running
running = true
$.ajax
type: 'POST',
url: $(this).data('url'),
data: $(this).parents('form').serialize(),
dataType: 'script',
success: (data) ->
running = false
- d3-js快速事件调用问题
- 使用按钮OnClick事件调用Javascript函数
- 了解在JavaScript中(在IE中)对某个事件调用了什么函数
- 如何使用onclick事件调用AngularJS控制器
- 无法从onclick事件调用JS函数
- 当多个 JS 事件调用同一个函数时,如何处理它们
- 为什么我从 JSLint 获得从事件调用的函数的“超出范围”
- 你能用onblur事件调用一个外部Javascript吗
- jquery mobile,从事件调用转换
- 如何使用C#为特定按钮事件调用JavaScript方法
- 如何在函数内部定义一个变量以供事件调用
- 如何从onClick事件调用对象函数
- 使用promise.then时,是否可以保留在单击事件调用堆栈中
- 如何断言间谍是使用jasmine通过点击事件调用的
- 使用AngularJS对超快速keyup和keydown事件调用函数
- 为同一标记中的两个不同事件调用两个javascript方法
- 事件调用方似乎无法正常工作
- 事件调用和范围问题
- 如何在 ng-repeat 中将变量值附加到事件调用
- j查询点击事件;调用特定函数(如果可用)