我想在用户完成在文本框中的输入后触发ajax请求。我不希望它在用户每次输入字母时都运行该函数,因为这会导致很多ajax请求,但是我也不希望他们也必须按下Enter键。
有没有一种方法可以让我检测用户何时完成键入,然后再执行ajax请求?
在这里使用jQuery!戴夫
我想在用户完成在文本框中的输入后触发ajax请求。我不希望它在用户每次输入字母时都运行该函数,因为这会导致很多ajax请求,但是我也不希望他们也必须按下Enter键。
有没有一种方法可以让我检测用户何时完成键入,然后再执行ajax请求?
在这里使用jQuery!戴夫
Answers:
因此,我猜测完成键入意味着您只需停顿一会儿,例如5秒钟。因此,请记住,让我们在用户释放按键时启动计时器,并在用户按下按键时清除它。我决定有问题的输入将是#myInput。
做一些假设...
//setup before functions
var typingTimer; //timer identifier
var doneTypingInterval = 5000; //time in ms, 5 second for example
var $input = $('#myInput');
//on keyup, start the countdown
$input.on('keyup', function () {
clearTimeout(typingTimer);
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
//on keydown, clear the countdown
$input.on('keydown', function () {
clearTimeout(typingTimer);
});
//user is "finished typing," do something
function doneTyping () {
//do something
}
doneTyping
在示例中看到一些评论,其中回调函数立即运行。这通常是由于不小心()
在函数名称之后添加了结果。请注意,它应该读setTimeout(doneTyping,
不setTimeout(doneTyping(),
上面选择的答案不起作用。
由于偶尔会多次设置typeingTimer(对于快速打字机等,在按下键盘键之前会先按下两次键盘键),因此无法正确清除。
下面的解决方案解决了此问题,并在完成OP请求后将在X秒后调用。它还不再需要冗余的keydown功能。我还添加了一个检查,以便在您输入为空时不会发生函数调用。
//setup before functions
var typingTimer; //timer identifier
var doneTypingInterval = 5000; //time in ms (5 seconds)
//on keyup, start the countdown
$('#myInput').keyup(function(){
clearTimeout(typingTimer);
if ($('#myInput').val()) {
typingTimer = setTimeout(doneTyping, doneTypingInterval);
}
});
//user is "finished typing," do something
function doneTyping () {
//do something
}
和香草JavaScript解决方案中的相同代码:
//setup before functions
let typingTimer; //timer identifier
let doneTypingInterval = 5000; //time in ms (5 seconds)
let myInput = document.getElementById('myInput');
//on keyup, start the countdown
myInput.addEventListener('keyup', () => {
clearTimeout(typingTimer);
if (myInput.value) {
typingTimer = setTimeout(doneTyping, doneTypingInterval);
}
});
//user is "finished typing," do something
function doneTyping () {
//do something
}
该解决方案确实使用了ES6,但是在这里没有必要。只需将替换为let
,var
然后将箭头功能替换为常规功能即可。
$('#myInput').on('input', function() {
,如果你想这与复制和粘贴的工作。如果输入为空,我看不到要检查的地方。假设他想删除他键入的内容将无法进行ajax调用。
if ($('#myInput').val)
不是if ($('#myInput').val())
呢?应该.val
是功能吗?
这只是一条线与underscore.js防抖动功能:
$('#my-input-box').keyup(_.debounce(doSomething , 500));
这基本上是说我停止输入500毫秒后的doSomething。
有关更多信息:http : //underscorejs.org/#debounce
Uncaught ReferenceError: _ is not defined
是的,您可以为每个会触发ajax请求的按键事件设置2秒的超时时间。您还可以存储XHR方法,并在随后的按键事件中中止该方法,从而节省更多带宽。这是我为我的自动完成脚本编写的。
var timer;
var x;
$(".some-input").keyup(function () {
if (x) { x.abort() } // If there is an existing XHR, abort it.
clearTimeout(timer); // Clear the timer so we don't end up with dupes.
timer = setTimeout(function() { // assign timer a new timeout
x = $.getJSON(...); // run ajax request and store in x variable (so we can cancel)
}, 2000); // 2000ms delay, tweak for faster/slower
});
希望这可以帮助,
马可
var timer;
var timeout = 1000;
$('#in').keyup(function(){
clearTimeout(timer);
if ($('#in').val) {
timer = setTimeout(function(){
//do stuff here e.g ajax call etc....
var v = $("#in").val();
$("#out").html(v);
}, timeout);
}
});
此处的完整示例:http : //jsfiddle.net/ZYXp4/8/
我喜欢超现实梦的答案,但是我发现我的“ doneTyping”函数会在每次按键时触发,即,如果您真正快速地键入“ Hello”的话;该函数将触发5次,而不是在您停止键入时仅触发一次。
问题在于javascript setTimeout函数似乎不会覆盖或杀死已设置的任何旧超时,但是如果您自己进行操作,它将起作用!因此,如果设置了typeTimer,我只是在setTimeout之前添加了clearTimeout调用。见下文:
//setup before functions
var typingTimer; //timer identifier
var doneTypingInterval = 5000; //time in ms, 5 second for example
//on keyup, start the countdown
$('#myInput').on("keyup", function(){
if (typingTimer) clearTimeout(typingTimer); // Clear if already set
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
//on keydown, clear the countdown
$('#myInput').on("keydown", function(){
clearTimeout(typingTimer);
});
//user is "finished typing," do something
function doneTyping () {
//do something
}
注意:我希望将其添加为“超现实梦想”答案的注释,但我是新用户,并且信誉不足。抱歉!
修改接受的答案以处理其他情况,例如粘贴:
//setup before functions
var typingTimer; //timer identifier
var doneTypingInterval = 2000; //time in ms, 2 second for example
var $input = $('#myInput');
// updated events
$input.on('input propertychange paste', function () {
clearTimeout(typingTimer);
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
//user is "finished typing," do something
function doneTyping () {
//do something
}
我认为在这种情况下,keyDown事件不是必需的(请告诉我为什么我错了)。在我的(非jquery)脚本中,类似的解决方案如下所示:
var _timer, _timeOut = 2000;
function _onKeyUp(e) {
clearTimeout(_timer);
if (e.keyCode == 13) { // close on ENTER key
_onCloseClick();
} else { // send xhr requests
_timer = window.setTimeout(function() {
_onInputChange();
}, _timeOut)
}
}
这是我对Stack Overflow的第一个答复,所以我希望有一天能对某人有所帮助:)
声明以下delay
功能:
var delay = (function () {
var timer = 0;
return function (callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})()
然后使用它:
let $filter = $('#item-filter');
$filter.on('keydown', function () {
delay(function () {
console.log('this will hit, once user has not typed for 1 second');
}, 1000);
});
较晚的答案,但我要添加它,因为它是在2019年,并且完全可以使用漂亮的ES6来实现,没有第三方库,而且我发现大多数高度评价的答案很庞大,并且变量太多。
优雅的解决方案摘自这篇出色的博客文章。
function debounce(callback, wait) {
let timeout;
return (...args) => {
const context = this;
clearTimeout(timeout);
timeout = setTimeout(() => callback.apply(context, args), wait);
};
}
window.addEventListener('keyup', debounce( () => {
// code you would like to run 1000ms after the keyup event has stopped firing
// further keyup events reset the timer, as expected
}, 1000))
我觉得该input
事件的解决方案有点简单:
var typingTimer;
var doneTypingInterval = 500;
$("#myInput").on("input", function () {
window.clearTimeout(typingTimer);
typingTimer = window.setTimeout(doneTyping, doneTypingInterval);
});
function doneTyping () {
// code here
}
同意@going的答案。另一个适用于我的类似解决方案是以下解决方案。唯一的区别是我使用的是.on(“ input” ...)而不是keyup。这仅捕获输入中的更改。其他键(如Ctrl,Shift等)将被忽略
var typingTimer; //timer identifier
var doneTypingInterval = 5000; //time in ms (5 seconds)
//on input change, start the countdown
$('#myInput').on("input", function() {
clearTimeout(typingTimer);
typingTimer = setTimeout(function(){
// doSomething...
}, doneTypingInterval);
});
我只是想出一个简单的代码来等待用户完成输入:
步骤1.将timeout设置为null,然后在用户键入时清除当前超时。
步骤2.在触发keyup事件之前,将清除超时触发到变量定义。
步骤3.将超时定义为上面声明的变量;
<input type="text" id="input" placeholder="please type" style="padding-left:20px;"/>
<div class="data"></div>
JavaScript代码
var textInput = document.getElementById('input');
var textdata = document.querySelector('.data');
// Init a timeout variable to be used below
var timefired = null;
// Listen for keystroke events
// Init a timeout variable to be used below
var timefired = null;// Listen for keystroke events
textInput.onkeyup = function (event) {
clearTimeout(timefired);
timefired = setTimeout(function () {
textdata.innerHTML = 'Input Value:'+ textInput.value;
}, 600);
};
我正在列表中实施搜索,因此需要基于Ajax的搜索。这意味着在每次关键更改时,应更新并显示搜索结果。这导致发送到服务器的ajax调用太多,这不是一件好事。
经过一些工作后,我采取了一种在用户停止键入时ping服务器的方法。
这个解决方案为我工作:
$(document).ready(function() {
$('#yourtextfield').keyup(function() {
s = $('#yourtextfield').val();
setTimeout(function() {
if($('#yourtextfield').val() == s){ // Check the value searched is the latest one or not. This will help in making the ajax call work when client stops writing.
$.ajax({
type: "POST",
url: "yoururl",
data: 'search=' + s,
cache: false,
beforeSend: function() {
// loading image
},
success: function(data) {
// Your response will come here
}
})
}
}, 1000); // 1 sec delay to check.
}); // End of keyup function
}); // End of document.ready
您会注意到,在实现此功能时无需使用任何计时器。
这是我写的一个简单的JS代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt-br" lang="pt-br">
<head><title>Submit after typing finished</title>
<script language="javascript" type="text/javascript">
function DelayedSubmission() {
var date = new Date();
initial_time = date.getTime();
if (typeof setInverval_Variable == 'undefined') {
setInverval_Variable = setInterval(DelayedSubmission_Check, 50);
}
}
function DelayedSubmission_Check() {
var date = new Date();
check_time = date.getTime();
var limit_ms=check_time-initial_time;
if (limit_ms > 800) { //Change value in milliseconds
alert("insert your function"); //Insert your function
clearInterval(setInverval_Variable);
delete setInverval_Variable;
}
}
</script>
</head>
<body>
<input type="search" onkeyup="DelayedSubmission()" id="field_id" style="WIDTH: 100px; HEIGHT: 25px;" />
</body>
</html>
您可以使用onblur事件来检测文本框何时失去焦点: https //developer.mozilla.org/en/DOM/element.onblur
如果您关心用户键入一堆东西然后坐在那里而文本框仍处于焦点的情况,则这与“停止键入”不同。
为此,我建议将setTimeout绑定到onclick事件,并假设经过x次没有按键输入的时间之后,用户已停止键入。
为什么不只使用onfocusout?
https://www.w3schools.com/jsreF/event_onfocusout.asp
如果是表单,他们将始终保留每个输入字段的焦点,以便单击“提交”按钮,因此您知道没有任何输入会错过调用其onfocusout事件处理程序的机会。
如果用户有必要离开该领域,我们可以在Javascript中使用“ onBlur”代替Onchange
<TextField id="outlined-basic" variant="outlined" defaultValue={CardValue} onBlur={cardTitleFn} />
如果没有必要,设置计时器将是一个不错的选择。
不知道我的需求是否有点奇怪,但是我需要与此类似的东西,这就是我最终使用的东西:
$('input.update').bind('sync', function() {
clearTimeout($(this).data('timer'));
$.post($(this).attr('data-url'), {value: $(this).val()}, function(x) {
if(x.success != true) {
triggerError(x.message);
}
}, 'json');
}).keyup(function() {
clearTimeout($(this).data('timer'));
var val = $.trim($(this).val());
if(val) {
var $this = $(this);
var timer = setTimeout(function() {
$this.trigger('sync');
}, 2000);
$(this).data('timer', timer);
}
}).blur(function() {
clearTimeout($(this).data('timer'));
$(this).trigger('sync');
});
这使我可以在应用程序中包含以下元素:
<input type="text" data-url="/controller/action/" class="update">
当用户“完成键入”(2秒钟不执行任何操作)或转到另一个字段(元素模糊)时,哪个更新
如果您需要等到用户输入完毕,请使用以下简单命令:
$(document).on('change','#PageSize', function () {
//Do something after new value in #PageSize
});
带有ajax调用的完整示例-适用于我的寻呼机-每个列表的项目计数:
$(document).ready(function () {
$(document).on('change','#PageSize', function (e) {
e.preventDefault();
var page = 1;
var pagesize = $("#PageSize").val();
var q = $("#q").val();
$.ajax({
url: '@Url.Action("IndexAjax", "Materials", new { Area = "TenantManage" })',
data: { q: q, pagesize: pagesize, page: page },
type: 'post',
datatype: "json",
success: function (data) {
$('#tablecontainer').html(data);
// toastr.success('Pager has been changed', "Success!");
},
error: function (jqXHR, exception) {
ShowErrorMessage(jqXHR, exception);
}
});
});
});
所有其他答案仅适用于一个控件(包括我的其他答案)。如果您每页有多个控件(例如,购物车中的控件),则只会调用用户键入内容的最后一个控件。就我而言,这当然不是所希望的行为-每个控件都应具有自己的计时器。
要解决此问题,您只需要将ID传递给函数并维护timeoutHandles字典,如以下代码所示:
功能声明:
var delayUserInput = (function () {
var timeoutHandles = {};
return function (id, callback, ms) {
if (timeoutHandles[id]) {
clearTimeout(timeoutHandles[id]);
}
timeoutHandles[id] = setTimeout(callback, ms);
};
})();
功能用法:
delayUserInput('yourID', function () {
//do some stuff
}, 1000);
哇,连3条评论都非常正确!
空输入不是跳过函数调用的原因,例如,我在重定向之前从url中删除了浪费参数
.on ('input', function() { ... });
应该用来触发keyup
,paste
并且change
事件
肯定.val()
或.value
必须使用
您可以使用$(this)
内部事件函数,而不是#id
使用多个输入
(我的决定)我使用匿名函数而不是doneTyping
in setTimeout
来方便地$(this)
从n.4 访问,但是您需要先保存它,例如var $currentInput = $(this);
编辑我看到有些人不了解复制粘贴准备好的代码的可能。你在这里
var typingTimer;
// 2
$("#myinput").on('input', function () {
// 4 3
var input = $(this).val();
clearTimeout(typingTimer);
// 5
typingTimer = setTimeout(function() {
// do something with input
alert(input);
}, 5000);
});
paste
,不使用this
等(我认为这很重要,但我不想迷失在大量评论中)