2010-03-21 148 views
5

我在网页上有一个文本框,其值要发送到XMLHttpRequest。现在我希望用户只需输入值,而不必按下按钮。但是,如果我只是将键盘事件发送给请求,那么每次按下键时它都会触发。Javascript:在用户停止输入时进行处理

所以基本上我想要的东西,这liek

function KeyUpEvent() 
{ 
    if (user is still typing) 
    return; 
    else 
    //do processing 
} 

这将是巨大的,如果解决方案可能来自普通的JavaScript或mootools的。我不想使用任何其他库。

+0

计时器永远不会满足。用户可能只是分心或输入比任何时候都慢的超时。我的解决方案是唯一合理的解决方案,并且是用户期望与字段交互的方式,并且不需要任何按钮。如果您不知道值的长度,则不知道用户是否完成。那么你就有冒险传递用户不想或不期望的价值,他们的体验只会让你的计时器沮丧,而不是增强。谈到UI体验,您最好坚持使用标准的使用场景。 – nicerobot 2010-03-21 23:36:16

回答

9

通常这样做的方法是通过在keyup事件中重新启动定时器。类似这样的:

var keyupTimer; 
function keyUpEvent(){ 
    clearTimeout(keyupTimer); 
    keyupTimer = setTimeout(sendInput,1000); // will activate when the user has stopped typing for 1 second 
} 

function sendInput(){ 
    alert("Do AJAX request"); 
} 
+0

你忘记了密码,如果他们决定在30秒内再次打字,该怎么办?您的活动仍然会触发 – 2011-03-26 02:56:46

+1

这不是一个有效的答案,会触发该事件[输入的字符数]次数 – 2014-02-19 10:17:07

9

基本上,你想在KeyUp上启动一个定时器,当KeyUp再次启动时,重置定时器。当用户停止输入时,计时器用完,并且您的请求可以在该点进行。

实施例:

var timout_id; 

function keyup_handler(event) { 
    if (timout_id) { 
    clearTimeout(timout_id); 
    } 

    timout_id = setTimeout(function(){ 
    alert('sending data: \n' + event.target.value) 
    }, 800); 
} 

功能仅附加在使用优选的方法的输入端,并与您的优选动作更换alert

当然有很多方法可以概括这种方法并使其更加可重用等,但我认为这说明了基本思想。

2

你永远不知道用户何时真的“完成”输入。用户可能会打喷嚏,休息或咖啡休息,然后继续打字。然而,如果你正在实现类似于自动完成机制的东西,你可以设置一个计时器(参见window.setTimeout(...)),以查看用户是否在一段时间内没有键入任何东西。如果在定时器运行时又遇到另一个按键事件,则可以启动定时器。

-1

使用onBlur或者onKeyDown来检查用户是否按下了回车/回车键。

+0

认真!!当它是唯一一个知道用户完成输入的真正手段时,向下投票?!也就是说,他们已经离开了现场,或者按下了一个表示他们想要提交的键。否则,无法知道。不是计时器,因为他们可能只是分心。 – nicerobot 2010-03-21 23:29:30

5

我一直用这个简单的函数来处理一个计时器,将触发一个回调函数,用户已经停止打字指定的时间量后:

var typewatch = (function(){ 
    var timer = 0; 
    return function(callback, ms){ 
    clearTimeout (timer); 
    timer = setTimeout(callback, ms); 
    } 
})(); 

使用(例如通过MooTools):

$('textInput').addEvent('keyup', function(e){ 
    typewatch(function() { 
    // executed only 500 ms after the last keyup event 
    // make Ajax request 
    }, 500); 
}); 

这个解决方案和解决方案等答案之间的主要区别在于:所有定时器逻辑由typewatch功能本身处理,事件处理程序并不需要知道关于计时器的事情,它只是调用该函数。此外,没有全局变量需要注意(定时器ID为而不是存储在全局变量中)。

1
var keyTimer; 
function onKeyUp(){ 
clearTimeout(keyTimer); 
setTimeout(stoppedTyping,1500); 
} 
function stoppedTyping(){ 
// Profit! $$$ 
} 

编辑:该死的忍者

0

我写了一个自定义的jQuery的事件,因为我用这个逻辑有很多:

jQuery.event.special.stoppedtyping = { 
    setup: function(data, namespaces) { 
    jQuery(this).bind('keyup', jQuery.event.special.stoppedtyping.keyuphandler); 
    }, 
    teardown: function(namespaces) { 
    jQuery(this).bind('keyup', jQuery.event.special.stoppedtyping.keyuphandler); 
    }, 
    keyuphandler: function(e) { 
    var interval = 1000; 
    var el = this; 

    if (jQuery.data(this, 'checklastkeypress') != null) { 
     clearTimeout(jQuery.data(this, 'checklastkeypress')); 
    } 

    var id = setTimeout(function() { 
     jQuery(el).trigger('stoppedtyping'); 
    }, interval); 
    jQuery.data(this, 'checklastkeypress', id); 
    } 
}; 

您可以使用它像这样:

$('input.title').bind('stoppedtyping', function() { 
    // run some ajax save operation 
}); 

出于某种原因,我永远无法使它与.live(...)一起工作。我不知道为什么......