如何延迟.keyup()处理函数,直到用户停止键入?

六月ゝ 毕业季﹏ 提交于 2020-01-07 02:25:52

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

我有一个搜索字段。 现在,它会搜索每个键。 因此,如果有人键入“ Windows”,它将使用AJAX搜索每个键入的内容:“ W”,“ Wi”,“ Win”,“ Wind”,“ Windo”,“ Window”,“ Windows”。

我希望有一个延迟,因此它仅在用户停止键入200毫秒时才搜索。

keyup函数中没有用于此的选项,我已经尝试过setTimeout ,但是它没有用。

我怎样才能做到这一点?


#1楼

延迟功能可在每次键入时调用。 需要jQuery 1.7.1或更高版本

jQuery.fn.keyupDelay = function( cb, delay ){
  if(delay == null){
    delay = 400;
  }
  var timer = 0;
  return $(this).on('keyup',function(){
    clearTimeout(timer);
    timer = setTimeout( cb , delay );
  });
}

用法: $('#searchBox').keyupDelay( cb );


#2楼

该函数从Gaten的答案中扩展了该函数,以使元素返回:

$.fn.delayKeyup = function(callback, ms){
    var timer = 0;
    var el = $(this);
    $(this).keyup(function(){                   
    clearTimeout (timer);
    timer = setTimeout(function(){
        callback(el)
        }, ms);
    });
    return $(this);
};

$('#input').delayKeyup(function(el){
    //alert(el.val());
    // Here I need the input element (value for ajax call) for further process
},1000);

http://jsfiddle.net/Us9bu/2/


#3楼

我很惊讶,没有人提到CMS非常好地剪掉多个输入的问题。

基本上,您必须为每个输入分别定义延迟变量。 否则,如果某人将文本输入第一个输入并快速跳转到其他输入并开始输入,则第一个输入的回调将不会被调用!

请参阅以下基于其他答案的代码:

(function($) {
    /**
     * KeyUp with delay event setup
     * 
     * @link http://stackoverflow.com/questions/1909441/jquery-keyup-delay#answer-12581187
     * @param function callback
     * @param int ms
     */
    $.fn.delayKeyup = function(callback, ms){
            $(this).keyup(function( event ){
                var srcEl = event.currentTarget;
                if( srcEl.delayTimer )
                    clearTimeout (srcEl.delayTimer );
                srcEl.delayTimer = setTimeout(function(){ callback( $(srcEl) ); }, ms);
            });

        return $(this);
    };
})(jQuery);

此解决方案将setTimeout引用保留在输入的delayTimer变量内。 还将fazzyx建议将element的引用传递给回调。

在IE6、8(comp-7),8和Opera 12.11中进行了测试。


#4楼

这是CMS的解决方案,但为我解决了一些关键问题:

  • 支持多个输入,延迟可以同时运行。
  • 忽略没有更改值的键事件(例如Ctrl,Alt + Tab)。
  • 解决竞争条件(执行回调且值已更改时)。
var delay = (function() {
    var timer = {}
      , values = {}
    return function(el) {
        var id = el.form.id + '.' + el.name
        return {
            enqueue: function(ms, cb) {
                if (values[id] == el.value) return
                if (!el.value) return
                var original = values[id] = el.value
                clearTimeout(timer[id])
                timer[id] = setTimeout(function() {
                    if (original != el.value) return // solves race condition
                    cb.apply(el)
                }, ms)
            }
        }
    }
}())

用法:

signup.key.addEventListener('keyup', function() {
    delay(this).enqueue(300, function() {
        console.log(this.value)
    })
})

该代码以我喜欢的风格编写,您可能需要添加一堆分号。

注意事项:

  • 根据表单ID和输入名称生成唯一ID,因此必须定义它们并使其唯一,否则您可以根据情况进行调整。
  • 延迟返回一个易于扩展以满足您自己需求的对象。
  • 用于延迟原始元素绑定到回调,所以this作品如预期(如在该示例中)。
  • 空值将在第二次验证中被忽略。
  • 注意排队 ,我希望它首先等待毫秒,但您可能需要切换参数以匹配setTimeout

我使用的解决方案增加了另一层次的复杂性,例如,允许您取消执行,但这是一个良好的基础。


#5楼

根据CMS的答案,它只忽略不会改变值的关键事件。

var delay = (function(){
    var timer = 0;
    return function(callback, ms){
      clearTimeout (timer);
      timer = setTimeout(callback, ms);
    };
})(); 

var duplicateFilter=(function(){
  var lastContent;
  return function(content,callback){
    content=$.trim(content);
    if(content!=lastContent){
      callback(content);
    }
    lastContent=content;
  };
})();

$("#some-input").on("keyup",function(ev){

  var self=this;
  delay(function(){
    duplicateFilter($(self).val(),function(c){
        //do sth...
        console.log(c);
    });
  }, 1000 );


})
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!