我想在停止在输入文本框中键入(而不是在键入时)字符之后立即触发事件.

I've tried with:

$('input#username').keypress(function() {
    var _this = $(this); // copy of this object for further usage

    setTimeout(function() {
        $.post('/ajax/fetch', {
            type: 'username',
            value: _this.val()
        }, function(data) {
            if(!data.success) {
                // continue working
            } else {
                // throw an error
            }
        }, 'json');
    }, 3000);
});

但是这个示例 for each 键入的字符生成一个超时,如果我键入20个字符,我会收到大约20个Ajax请求.

On this fiddle我用一个简单的alert 而不是AJAX来演示同样的问题.

Is there a solution for this or I'm just using a bad approach for this?

推荐答案

You'll have to use a setTimeout (like you are) but also store the reference so you can keep resetting the limit. Something like:

//
// $('#element').donetyping(callback[, timeout=1000])
// Fires callback when a user has finished typing. This is determined by the time elapsed
// since the last keystroke and timeout parameter or the blur event--whichever comes first.
//   @callback: function to be called when even triggers
//   @timeout:  (default=1000) timeout, in ms, to to wait before triggering event if not
//              caused by blur.
// Requires jQuery 1.7+
//
;(function($){
    $.fn.extend({
        donetyping: function(callback,timeout){
            timeout = timeout || 1e3; // 1 second default timeout
            var timeoutReference,
                doneTyping = function(el){
                    if (!timeoutReference) return;
                    timeoutReference = null;
                    callback.call(el);
                };
            return this.each(function(i,el){
                var $el = $(el);
                // Chrome Fix (Use keyup over keypress to detect backspace)
                // thank you @palerdot
                $el.is(':input') && $el.on('keyup keypress paste',function(e){
                    // This catches the backspace button in chrome, but also prevents
                    // the event from triggering too preemptively. Without this line,
                    // using tab/shift+tab will make the focused element fire the callback.
                    if (e.type=='keyup' && e.keyCode!=8) return;
                    
                    // Check if timeout has been set. If it has, "reset" the clock and
                    // start over again.
                    if (timeoutReference) clearTimeout(timeoutReference);
                    timeoutReference = setTimeout(function(){
                        // if we made it here, our timeout has elapsed. Fire the
                        // callback
                        doneTyping(el);
                    }, timeout);
                }).on('blur',function(){
                    // If we can, fire the event since we're leaving the field
                    doneTyping(el);
                });
            });
        }
    });
})(jQuery);

$('#example').donetyping(function(){
  $('#example-output').text('Event last fired @ ' + (new Date().toUTCString()));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<input type="text" id="example" />
<p id="example-output">Nothing yet</p>

That will execute when:

  1. 超时已过,或
  2. The user switched fields (blur event)

(以先到者为准)

Jquery相关问答推荐

更改后如何使用 jQuery Select CSS 类

Flask,如何为ajax调用返回成功状态码

动态加载 css 样式表在 IE 上不起作用

jQuery:使用变量作为 Select 器

为什么 jQuery 不使用 requestAnimationFrame?

在 select2 中使用 AJAX 进行标记

如何设置缓存:jQuery.get 调用中的 false

jQuery/JavaScript 碰撞检测

为特定请求禁用 ajaxStart() 和 ajaxStop()

jQuery计算所有文本字段中的值的总和

使用 jQuery Select 焦点文本在 Safari 和 Chrome 中不起作用

按文本 Select 链接(完全匹配)

带有回调ajax json的jQuery自动完成

无法更新数据属性值

你如何使用 jquery 淡入/淡出背景 colored颜色 ?

设置 JQuery event.preventDefault() 时绕过 window.open 上的弹出窗口阻止程序

jQuery select2 获取 Select 标签的值?

使用javascript将HTML页面中的div下载为pdf

删除所有以某个字符串开头的类

detach()、hide() 和 remove() 之间的区别 - jQuery