jQuery值改变事件延迟

33
我希望在用户完成在文本框中输入后的2秒钟内执行一个函数。如果他们在1秒钟后继续输入,则延迟时间会重新设置为2秒。
它应该类似于自动完成框。
我知道有两个事件:changekeyup。使用change的问题是必须失去焦点才能触发。 对于keyup,如果他们使用鼠标粘贴文本呢?
请问如何解决此问题?
5个回答

31

有HTML5的oninput事件,被当前所有主流浏览器支持,可以在IE8及更低版本中使用:

$("#myInput").bind("input", function () {
    // ...
})

一个非常简单的跨浏览器(cross browser)方法是:

$("#myInput").bind("input propertychange", function (evt) {
    // If it's the propertychange event, make sure it's the value that changed.
    if (window.event && event.type == "propertychange" && event.propertyName != "value")
        return;

    // Clear any previously set timer before setting a fresh one
    window.clearTimeout($(this).data("timeout"));
    $(this).data("timeout", setTimeout(function () {
        // Do your thing here
    }, 2000));
});

在IE 9中,这将使事件触发两次(一次是propertychange,一次是input),但由于事件处理程序的特性,这并不重要。


在你的示例中,事件类型应该是evt.type而不是event.type吗?看起来不错,我想我可以借用这个。IE7会在失焦事件上触发多个propertychanges,这段代码能够捕获它们并且只处理一次吗?此外,定时器的目的是什么? - armyofda12mnkeys
1
@armyofda12mnkeys:不,event.type是正确的,它正在寻找IE中提供的全局event对象。如果你想更加谨慎,可以将其更改为window.event.*。它只处理对value属性的更改,如果它触发多次,则会取消先前设置的计时器。 - Andy E

13

您可以绑定 input 事件以及用于旧版浏览器的回退的 keyup 事件。然后,您可以启动一个计时器,在检测到用户操作时重置计时器。通过将计时器句柄保存在当前元素的数据中,确保多个元素不会互相干扰。

$('input').bind('input keyup', function(){
    var $this = $(this);
    var delay = 2000; // 2 seconds delay after last input

    clearTimeout($this.data('timer'));
    $this.data('timer', setTimeout(function(){
        $this.removeData('timer');

        // Do your stuff after 2 seconds of last user input
    }, delay));
});

2
propertychangekeyup更好。它被Internet Explorer支持,并且每当用户执行某些操作来更改输入字段的value属性时,它就会触发,使其与input一样好。请参见我上面的答案。 - Andy E
选择具有此目的的更改。 - pebbo

2
您可以同时使用change和keyup事件:
var globalTimeout;

$(function() {
    $("#myInput").change(initTimer).keyup(initTimer);
});

function initTimer() {
    if (globalTimeout) clearTimeout(globalTimeout);
    globalTimeout = setTimeout(handler, 2000);
}

function handler() {
    ...
}

0

keyup 不是用来检测用户输入的好事件。它只有在用户抬起手指离开键盘时才触发,并且仅适用于键盘输入(不包括粘贴、拖放、拼写检查等)。 - Andy E
@Andy:请查看演示。jQuery 1.6也支持粘贴! - Naveed Ahmad
@kingjiv 和 @Andy,我的错误,是的,它不能与鼠标交互一起使用,但是如果我们绑定 input 事件,我们可以这样做,就像 @Andy 所做的那样。 - Naveed Ahmad

0
我会这样做:
$("selector").keyup(function(){
   if(typeof(window.delayer) != 'undefined')
      clearTimeout(window.delayer);
   window.delayer = setTimeout(function_you_want_to_get_execute_with_delay, 2000);
});

祝你好运


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接