当用户在键入时暂停(而不是在每次按键后)时,我想触发一个ajax动作。所以我做了这样的事情:
当用户在空闲3秒后停止输入时,将执行完成功能...(它是 - 但为什么3次长短语 - 我希望它只运行一次,因为我在每次keydown后清除超时)。有什么问题?
var timer;
var interval = 3000;
$('#inp').keyup(function() {
timer = setTimeout(done, interval);
});
$('#inp').keydown(function() {
clearTimeout(timer)
});
function done() {
console.log('ajax');
}
关于jsfiddle的工作示例: http://jsfiddle.net/vtwVH/
答案 0 :(得分:9)
键入时,有时可能会在释放第一个键之前按下另一个键。你可能没有注意到这一点,特别是如果你输入一个长短语。在这种情况下,事件的顺序不是down up down up
而是down down up up
,因此将设置两个超时。
在设置之前清除超时(在同一个事件处理程序中)更加一致。
答案 1 :(得分:7)
问题是你正在覆盖你的keydown事件中的timer
变量。
因此,如果您在Timout被清除之前按下另一个键例如继续按住
对timeOut的引用将丢失,您无法再次清除它。
要解决此问题,您只需清除并在keyUp
事件中设置计时器,如
var timer;
var interval = 3000;
$('#inp').keyup(function(e){
if(timer) {
clearTimeout(timer);
}
timer = setTimeout(done, interval);
});
function done() {
console.log('ajax');
}
继承人工作fiddle
答案 2 :(得分:1)
事件似乎不遵循严格的顺序规则,第二个keydown比第一个keyup早,所以计时器多次初始化。
试试这个mod:
$('#inp').keyup(function(){
clearTimeout(timer);
timer = setTimeout(done, interval);
});
答案 3 :(得分:0)
请确保清除间隔:
var timer;
var interval = 3000;
$('#inp').keyup(function(){
clearTimeout(timer)
timer = setTimeout(done, interval);
});
$('#inp').keydown(function(){
clearTimeout(timer)
});
function done() {
console.log('ajax');
}
答案 4 :(得分:0)
除非用户输入的速度非常慢,否则keydown
和keyup
将不会按您认为的顺序排列。例如,您可以获得两个keydown
个事件,然后是两个keyup
个事件。如果你不处理,第二个keyup
事件将启动另一个计时器并覆盖对第一个计时器的引用,以便它不会被清除。
跟踪超时是否正在运行,并在keyup
中清除超时(如果它正在运行):
var timer = null;
var interval = 3000;
$('#inp').keyup(function(){
if (timer != null) {
window.clearTimeout(timer)
}
timer = window.setTimeout(done, interval);
});
$('#inp').keydown(function(){
if (timer != null) {
window.clearTimeout(timer);
timer = null;
}
});
function done() {
timer = null;
console.log('ajax');
}