Javascript 如何触发';在用户暂停键入之前,是否会延迟?

Javascript 如何触发';在用户暂停键入之前,是否会延迟?,javascript,jquery,ajax,Javascript,Jquery,Ajax,我有一个textarea,人们可以在其中输入一些文本(自然),我希望这样做,以便不时发出AJAX请求,以获得有关textarea的一些建议(比如堆栈溢出的相关问题,但是对于textarea,而不是文本输入)。问题是我不能在每次按键时都做一个AJAX请求(这将是无用的,并且非常消耗资源),我不确定什么是最有效的方法(每X个字?每X秒?或者其他什么?) 这样做的最佳方式是什么 提前感谢您。如果您对jQuery解决方案感兴趣,这是一个很好的实现 每次都重新设计轮子是没有意义的。我个人会使用一个setI

我有一个textarea,人们可以在其中输入一些文本(自然),我希望这样做,以便不时发出AJAX请求,以获得有关textarea的一些建议(比如堆栈溢出的相关问题,但是对于textarea,而不是文本输入)。问题是我不能在每次按键时都做一个AJAX请求(这将是无用的,并且非常消耗资源),我不确定什么是最有效的方法(每X个字?每X秒?或者其他什么?)

这样做的最佳方式是什么


提前感谢您。

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


每次都重新设计轮子是没有意义的。

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

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

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 );

另一种选择是使用一个名为jQuery的小jQuery插件。它使用与已接受答案相同的setTimeout技术,但透明地处理超时,因此代码更易于阅读。可以在github上看到

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

如果你在网站上经常使用这个功能,并且不想跟踪所有的setTimeout引用等,那么我将它打包成一个可用的插件


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

如果您使用的是lodash.js(或下划线.js),则可以使用

示例(用于keyup的jQuery):


你要找的是
去抖动
。以下是本机JavaScript中的通用算法:

function debounce(fn, duration) {
  var timer;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(fn, duration)
  }
}
下面是一个如何将其用于
onkeyup
事件的示例:

功能去抖动(fn,持续时间){
无功定时器;
返回函数(){
清除超时(计时器);
定时器=设置超时(fn,持续时间);
}
}
const txt=document.querySelector(“#txt”)
const out=document.querySelector(“#out”)
const status=document.querySelector(“#status”)
const onReady=()=>{
txt.addEventListener('keydown',()=>{
out.classList.remove('idle'))
out.classList.add('typing')
status.textContent='typing…'
})
txt.addEventListener('keyup',去盎司(()=>{
out.classList.remove('typing')
out.classList.add('idle'))
status.textContent='idle…'
}, 800))
}
document.addEventListener('DOMContentLoaded',onReady)
#包装器{
宽度:300px;
}
输入{
填充:8px;
字体大小:16px;
宽度:100%;
框大小:边框框;
}
#出去{
利润率:10px0;
填充:8px;
宽度:100%;
框大小:边框框;
}
.打字{
背景:#A00;
颜色:#FFF;
}
.闲置{
背景:#0A0;
颜色:#FFF;
}

状态:正在等待。。。

这对我不起作用,因为我不想更新textarea或任何有建议的内容。我只想发出一个AJAX请求,以获取页面中另一个元素的内容,每X次击键,或者用户每X秒键入一次,等等。我只是想知道什么是最有效的选择。这是普遍接受的“正确”方式。说得好。谢谢蒂姆,绝妙的解决方案:如果你想捕获退格键事件,就使用Duse onkeyup。@barkmadley:如果你不想阻止它的默认操作,那就好了。您可以在按键处理程序中可靠地捕获退格键事件,并阻止默认操作。@Tim Down:代码运行良好,但有一个问题:如果您在文本区域有焦点的情况下将Tab键(在Windows中)切换到另一个应用程序,然后再次将Tab键切换回,则会触发回调函数。不应该,因为没有按下任何键。我不知道如何解决这个问题。这需要setInterval永远运行。Tim的解决方案更加优雅,只有在有人真正与textbox交互时才运行。永远运行,直到页面卸载。另外,如果您希望在用户键入时提供一些反馈,我的解决方案会更好,因为如果用户每秒键入的速度超过一个键,它有机会发送请求。我不是说Tim的解决方案不优雅,但在某些情况下,它不是取决于应用程序的解决方案。可能的@kenorb重复问题实际上是第一个问题,您引用的问题被视为该问题的重复,但是管理员们不想结束这个问题,因为标题更好,它有大约132931个视图,这是非常值得注意的。这并不重要,因为它更老,另一个有更多的投票和视图,请参阅:。标题始终可以编辑为更好的标题。他们总是可以的。看到我2009年的问题在2016年被审查,真是太酷了。谈论彻底的节制。这应该是我公认的解决方案。。。简单,干净,它让你在每一个事件监听器上使用它,你想。。。
function debounce(fn, duration) {
  var timer;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(fn, duration)
  }
}