我有一个输入字段,当有人开始输入时会生成自动建议。用户无需模糊或点击提交按钮即可显示建议。
当有人停止输入时,我想运行一个功能来跟踪向用户显示哪些产品,以及当前输入字段中的文本字符串。
我添加了一个'input'事件监听器,但我无法理解我的逻辑。
我想doStuff()
,如果它自上次输入事件以来至少已经过了1秒。麻烦的是,当用户开始输入时,我的脚本会被触发,因为它基于'change'事件监听器。
而且我认为必须有一种比我现在更合乎逻辑的方式。
此外,我担心“输入”事件会影响用户浏览器,因为它在每次击键时运行,也许有更好的方式?
不情愿地在下面显示我的代码块,即使它没有多大意义并且是我较弱的脚本时刻之一,更多地表明我一直在尝试不同的东西。宁愿选择忽略我一直使用的疯狂逻辑的解决方案。
当用户“已停止在输入中输入文字”时,我想doStuff(e)
这不是一个确切的定义。用户何时被认为已停止输入?现在我说1秒钟。
不想使用更改事件,因为它错过了许多用户不模糊的事件。
首选纯JS。
var input = document.querySelector('#search_input');
var newinput;
var lastinput;
var diff;
input.addEventListener('input', function(e) {
newinput = new Date();
if(!lastinput) {
lastinput = new Date()
}
diff = newinput - lastinput;
if(diff > 500 && diff < 2000) {
doStuff(e)
}
lastinput = newinput;
}, false);
答案 0 :(得分:5)
您可以将input
事件监听器与setTimeout()
和clearTimeout()
一起使用,如下所示:
var timeoutID;
document.querySelector('#search_input').addEventListener('input', function(e) {
clearTimeout(timeoutID);
timeoutID = setTimeout(function() {
alert("1 second has passed since any input was received.");
// doStuff()
}, 1000);
});
&#13;
<input id="search_input">
&#13;
setTimeout()
函数将在第一个参数中传递的函数排队,并在经过指定的毫秒数后执行。 clearTimeout()
函数根据setTimeout()
返回的ID取消当前计划的超时。
因此,我上面显示的函数基本上表示每当发生input
事件时,取消任何先前计划的超时,然后创建另一个。因此,内部函数中的代码只会在用户停止输入后大约1秒钟运行。
答案 1 :(得分:1)
该技术有时被称为&#34; debouncing&#34;。虽然像Underscore或Lodash这样的大量库有这个,但它可以在纯JavaScript中相当容易地完成。它包含了一个在超过去抖时间时调用的函数。它涉及使用setTimeout()
并在每次在输入上触发事件时清除并重置超时。如果事件有延迟且超时超时,则最终会触发去抖动功能。
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
使用它:
var myEfficientFn = debounce(function() {
// All the taxing stuff you do
}, 250);
element.addEventListener('keyup', myEfficientFn);
在您的情况下,您希望将事件添加到keyup
,keydown
,change
,cut
,copy
,{{1等等。
paste