在jQuery中调节事件调用
我有一个绑定到函数的keyup
事件,需要大约四分之一秒才能完成。
$("#search").keyup(function() { //code that takes a little bit to complete });
当用户input整个单词时,或者快速按下键时,该函数将被连续调用几次,这些操作都需要一段时间才能完成。
有没有办法遏制事件的电话,以便如果有几个快速连续,它只会触发最近被称为?
看看jQuery Debounce 。
$('#search').keyup($.debounce(function() { // Will only execute 300ms after the last keypress. }, 300));
这是一个不需要插件的潜在解决scheme。 使用布尔值来决定是否执行键控callback,或跳过它。
var doingKeyup = false; $('input').keyup(function(){ if(!doingKeyup){ doingKeyup=true; // slow process happens here doingKeyup=false; } });
你也可以使用优秀的Underscore / _库。
Josh的回答是目前最stream行的一个观点,你是否应该真正调节电话,或者是否需要删除电话。 差别有点微妙,但是_.debounce(function, wait, [immediate])
同时具有: _.debounce(function, wait, [immediate])
和_.throttle(function, wait, [options])
。
如果您还没有使用Underscore,请查看。 它可以使你的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);
我遇到这个问题,审查zurb基础的变化。 他们已经添加了自己的去抖和节stream方法 。 它看起来可能和他在回答中提到的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));
像这样的东西似乎最简单(没有外部库)的快速解决scheme(注意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