我正在研究一种自动完成功能的方法,以浏览表单的各个步骤。下面是代码,当输入5个字符时,它会移动到下一个元素。我的延迟效果很好,但如果在输入5个字符后字符被删除,我无法阻止它完成。无论输入中发生了什么变化,它都会在此之后立即触发焦点。
有什么想法吗?
var delay = (function(){
var timer = 0;
return function(callback, ms) {
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
$('input').keyup(function(){
if($(this).val().length == 5) {
delay(function(){ $("#saveForm2").focus(); }, 2000 );
}
})
答案 0 :(得分:3)
如果您正在寻找一种将超时实例与元素相关联的简便方法,请考虑使用jQuery的.data()
方法。
像这样。
$('input').keyup(function() {
var $th = $(this);
var data = $th.data();
if(data.timeout === undefined) {
data.timeout = null;
}
if ($th.val().length == 5) {
clearTimeout(data.timeout);
data.timeout = setTimeout(function() {
$("#saveForm2").focus();
}, 2000);
} else {
clearTimeout(data.timeout);
}
});
我不认为你使用封闭的方式是对的。我认为您需要将处理程序分配给闭包内的元素,因此它具有对该实例的本地引用。
编辑:使用之前存储的data()
引用效率更高。
答案 1 :(得分:0)
每次调用delay()
时,都会破坏超时句柄,这意味着您无法在事后处理它。它还意味着,如果我正确读取,那么每次达到5个字符时,您将要发出请求。尝试这样的事情:
var delayTimer;
var nextField = function() { $("#saveForm2").focus(); }
$('input').keyup(function(){
clearTimeout(delayTimer);
if($(this).val().length >= 5) {
delayTimer = setTimeout(nextField, 2000);
}
})
除非您在击键之间等待超过2秒,否则将发出不超过1个请求,并且b)如果您在超时到期之前退回5个字符以下将取消任何待处理请求。作为奖励,它不会创建一堆乱七八糟的匿名函数。