2009-10-25 23 views
30

我有一个textarea,人们在这里输入一些文本(自然),我想让它每隔一段时间都会产生一个AJAX请求,然后得到一些关于textarea是什么的建议(比如堆栈溢出的相关问题,但为textarea,而不是文本输入)。问题是,我无法在每次按键时发出一个AJAX请求(这是无用的,非常耗费资源),我不确定什么是最有效的方法(每X个字每X秒? 或者是其他东西?)。如何触发延迟直到用户暂停键入的onkeyup事件?

要做到这一点,最好的方法是什么?

预先感谢您。

+1

可能重复)延迟](http:// stackoverflow。com/questions/1909441/jquery-keyup-delay) – kenorb 2015-03-16 13:56:53

+0

@kenorb这个问题实际上是第一次的,你引用被认为是这个问题的重复,但管理员不想关闭这个问题,因为标题更好,它有约132931意见,这是非常了不起的。 – Adam 2016-07-27 18:57:10

+0

这没关系,这是更老的,另一个有更多的投票和意见,请参阅:[我应该举一个问题作为重复,如果它已收到更好的答案?](http://meta.stackoverflow.com/q/ 55075分之251938)。标题总是可以编辑得更好。他们可以总是[合并](http://meta.stackexchange.com/a/147651/191655)。 – kenorb 2016-07-27 19:03:15

回答

60

您可以将keypress事件处理程序与setTimeout组合在一起,以便在按键后一段时间内发送Ajax请求,取消并在定时器完成前发生另一次按键时重新启动计时器。假设你有id为“myTextArea”,并呼吁doAjaxStuff一个Ajax回调函数的textarea:

function addTextAreaCallback(textArea, callback, delay) { 
    var timer = null; 
    textArea.onkeypress = function() { 
     if (timer) { 
      window.clearTimeout(timer); 
     } 
     timer = window.setTimeout(function() { 
      timer = null; 
      callback(); 
     }, delay); 
    }; 
    textArea = null; 
} 

addTextAreaCallback(document.getElementById("myTextArea"), doAjaxStuff, 1000); 
+2

这是公认的“正确”方式。说得好。 – 2009-10-25 21:09:13

+0

谢谢蒂姆,辉煌的解决方案:D – 2009-10-27 00:44:36

+3

如果您希望能够捕获退格键事件,请使用onkeyup。 – barkmadley 2009-10-27 04:26:45

0

如果你对jQuery解决方案感兴趣,jQuery Suggest是一个很好的实现。

每次都没有意义重新发明轮子。

+0

这对我不起作用,因为我不想更新textarea或任何带有建议的东西。我只想发出一个AJAX请求来获取页面中的另一个元素的内容,每X次按键或用户输入的每X秒钟,或其他内容。只是想知道什么是最有效的选择。 – 2009-10-25 11:22:15

1

我个人会使用setInterval来监视textarea的变化,并且只在检测到更改时才执行AJAX回调。每一秒都应该足够快速和缓慢。

+0

这需要setInterval永远运行。 Tim的解决方案更加优雅,只有在有人真正与文本框进行交互时才会运行。 – 2009-10-25 21:10:22

+0

永远运行直到页面被卸载。此外,如果您希望在用户输入时提供一些反馈,我的解决方案会更好,因为如果用户每秒输入的键快于一个键,则有机会发送请求。我并不是说蒂姆的解决方案不够优雅,但在某些情况下,这不是解决方案,取决于应用程序。 – barkmadley 2009-10-26 08:11:01

9

另一种方法是使用一个小的jQuery插件称为bindWithDelay。它使用与接受的答案相同的setTimeout技术,但透明地处理超时,因此您的代码更容易阅读。在github上可以看到source code

$("#myTextArea").bindWithDelay("keypress", doAjaxStuff, 1000) 
0

如果您正在使用该网站围绕这个功能很多,不想跟踪所有的setTimeout裁判等等,然后我这个打包成可here插件的。

该插件为正常的$ .ajax方法添加了一些选项,用于缓冲和取消先前的ajax调用。

2

如果您使用的是underscore.js,则可以使用debounce function

例(jQuery的用于KEYUP):

$('#myTextArea').keyup(_.debounce(function(){ 
    alert('hello'); 
}, 500)); 
4

你在寻找什么叫debouncing。这里是一个通用的算法在本地JavaScript:

function debounce(fn, duration) { 
    var timer; 
    return function() { 
    clearTimeout(timer); 
    timer = setTimeout(fn, duration) 
    } 
} 

,这里是如何与onkeyup事件中使用它的一个例子:(单位:[jQuery的.keyup

function debounce(fn, duration) { 
 
    var timer; 
 
    return function(){ 
 
    clearTimeout(timer); 
 
    timer = setTimeout(fn, duration); 
 
    } 
 
} 
 

 
$(function(){ 
 
    
 
    $('#txtSearch').on('keyup', debounce(function(){ 
 
    
 
    alert('You paused your typing!'); 
 
    
 
    }, 500)); 
 
    
 
});
input{ 
 
    padding:.5em; 
 
    font-size:16px; 
 
    width:20em; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<input id="txtSearch" placeholder="Type here" />