我可以延迟 jquery 的 keyup 事件吗?
Posted
技术标签:
【中文标题】我可以延迟 jquery 的 keyup 事件吗?【英文标题】:Can I delay the keyup event for jquery? 【发布时间】:2012-04-15 12:30:17 【问题描述】:我将 rottentomatoes 电影 API 与 twitter 的 typeahead 插件结合使用,使用 bootstrap 2.0。我已经能够整合 API,但我遇到的问题是,在每个 keyup 事件之后,API 都会被调用。这一切都很好而且很花哨,但我宁愿在稍停片刻后拨打电话,让用户先输入几个字符。
这是我当前在 keyup 事件后调用 API 的代码:
var autocomplete = $('#searchinput').typeahead()
.on('keyup', function(ev)
ev.stopPropagation();
ev.preventDefault();
//filter out up/down, tab, enter, and escape keys
if( $.inArray(ev.keyCode,[40,38,9,13,27]) === -1 )
var self = $(this);
//set typeahead source to empty
self.data('typeahead').source = [];
//active used so we aren't triggering duplicate keyup events
if( !self.data('active') && self.val().length > 0)
self.data('active', true);
//Do data request. Insert your own API logic here.
$.getJSON("http://api.rottentomatoes.com/api/public/v1.0/movies.json?callback=?&apikey=MY_API_KEY&page_limit=5",
q: encodeURI($(this).val())
, function(data)
//set this to true when your callback executes
self.data('active',true);
//Filter out your own parameters. Populate them into an array, since this is what typeahead's source requires
var arr = [],
i=0;
var movies = data.movies;
$.each(movies, function(index, movie)
arr[i] = movie.title
i++;
);
//set your results into the typehead's source
self.data('typeahead').source = arr;
//trigger keyup on the typeahead to make it search
self.trigger('keyup');
//All done, set to false to prepare for the next remote query.
self.data('active', false);
);
);
是否可以设置一个小的延迟并避免在每次按键后调用 API?
【问题讨论】:
【参考方案1】:可以这样轻松完成:
var autocomplete = $('#searchinput').typeahead().on('keyup', delayRequest);
function dataRequest()
// api request here
function delayRequest(ev)
if(delayRequest.timeout)
clearTimeout(delayRequest.timeout);
var target = this;
delayRequest.timeout = setTimeout(function()
dataRequest.call(target, ev);
, 200); // 200ms delay
【讨论】:
这很好用,但似乎卡在一个循环中,每 200 毫秒调用一次 datarequest? 在您的代码中,您在 keyup 之后触发了 keyup:self.trigger('keyup')
。对于正确的 keyup 事件处理,您应该删除 ev.stopPropagation();
和 self.trigger('keyup')
【参考方案2】:
一般来说,这可以通过setTimeout
和clearTimeout
方法来实现:
var timer;
$('#textbox').keyup(function()
if (timer)
clearTimeout(timer);
timer = setTimeout('alert("Something cool happens here....");', 500);
);
setTimeout
将在指定的毫秒间隔后执行提供的 javascript。 clearTimeout
将取消此执行。
我还准备了jsFiddle demo,展示了运行中的代码 sn-p。
参考资料:
Javascript timing methods【讨论】:
【参考方案3】:对于使用 v0.11 of typeahead.js 并使用 Bloodhound 获取远程建议的人,您可以使用 rateLimitWait 选项来限制请求:
var search = new Bloodhound(
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote:
url: '/search?q=%QUERY',
rateLimitWait: 500
);
【讨论】:
【参考方案4】:不确定 Bootstrap 2.0 使用哪个版本进行预输入,但 v0.9.3 有一个隐藏在后台的 minLength 选项,但没有记录。
$('#people').typeahead(
name: 'people',
prefetch: './names.json',
minLength: 3
);
从这篇博文中发现:http://tosbourn.com/2013/08/javascript/setting-a-minimum-length-for-your-search-in-typeahead-js/
【讨论】:
【参考方案5】:而不是延迟,如果您只想允许用户在 ajax $.getJSON 请求之前输入几个字符,您可以修改 if 语句,以便用户必须输入最少数量的字符,例如3、在请求数据之前:
if( !self.data('active') && self.val().length >=3)
【讨论】:
以上是关于我可以延迟 jquery 的 keyup 事件吗?的主要内容,如果未能解决你的问题,请参考以下文章
primefaces keyup 或其他 ajax 事件延迟
jQuery 仅在附加了 jQuery 时才会触发 keyup 事件
在 JS/jQuery 中触发 keypress/keydown/keyup 事件?