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

I’ve got a search field. Right now it searches for every keyup. So if someone types “Windows”, it will make a search with AJAX for every keyup: “W”, “Wi”, “Win”, “Wind”, “Windo”, “Window”, “Windows”.

I want to have a delay, so it only searches when the user stops typing for 200 ms.

There is no option for this in the keyup function, and I have tried setTimeout, but it didn’t work.

How can I do that?

逆天小宇宙2020/03/11 20:34:56
// Get an global variable isApiCallingInProgress

//  check isApiCallingInProgress 
if (!isApiCallingInProgress) {
// set it to isApiCallingInProgress true
      isApiCallingInProgress = true;

      // set timeout
      setTimeout(() => {
         // Api call will go here

        // then set variable again as false
        isApiCallingInProgress = false;     
      }, 1000);
}
米亚Near2020/03/11 20:34:56

User lodash javascript library and use _.debounce function

changeName: _.debounce(function (val) {
  console.log(val)                
}, 1000)
梅西里2020/03/11 20:34:56

使用bindWithDelay jQuery插件:

element.bindWithDelay(eventType, [ eventData ], handler(eventObject), timeout, throttle)
前端猪猪GO2020/03/11 20:34:56

根据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 );


})
神无Green前端2020/03/11 20:34:56

采用

mytimeout = setTimeout( expression, timeout );

其中expression是要运行的脚本,超时是在运行之前等待的时间(以毫秒为单位)-这不会破坏脚本,而只是延迟了该部分的执行,直到完成超时为止。

clearTimeout(mytimeout);

将重置/清除超时,因此只要尚未执行该脚本就不会在表达式中运行该脚本(如取消)。

猪猪小卤蛋2020/03/11 20:34:55

我很惊讶,没有人提到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建议将元素的引用传递给回调。

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

古一L2020/03/11 20:34:55

如果有人希望延迟相同的功能,并且没有外部变量,则可以使用下一个脚本:

function MyFunction() {

    //Delaying the function execute
    if (this.timer) {
        window.clearTimeout(this.timer);
    }
    this.timer = window.setTimeout(function() {

        //Execute the function code here...

    }, 500);
}
LEY番长2020/03/11 20:34:55

使用标签延迟多功能通话

This is the solution i work with. It will delay the execution on ANY function you want. It can be the keydown search query, maybe the quick click on previous or next buttons ( that would otherwise send multiple request if quickly clicked continuously , and be not used after all). This uses a global object that stores each execution time, and compares it with the most current request.

So the result is that only that last click / action will actually be called, because those requests are stored in a queue, that after the X milliseconds is called if no other request with the same label exists in the queue!

function delay_method(label,callback,time){
    if(typeof window.delayed_methods=="undefined"){window.delayed_methods={};}  
    delayed_methods[label]=Date.now();
    var t=delayed_methods[label];
    setTimeout(function(){ if(delayed_methods[label]!=t){return;}else{  delayed_methods[label]=""; callback();}}, time||500);
  }

You can set your own delay time ( its optional, defaults to 500ms). And send your function arguments in a "closure fashion".

For example if you want to call the bellow function:

function send_ajax(id){console.log(id);}

为了防止出现多个send_ajax请求,可以使用以下方法延迟它们

delay_method( "check date", function(){ send_ajax(2); } ,600);

如果在600毫秒的时间内没有其他请求,则只有标签“检查日期”的每个请求都将被触发。此参数是可选的

标签独立(调用相同的目标函数),但同时运行两个:

delay_method("check date parallel", function(){send_ajax(2);});
delay_method("check date", function(){send_ajax(2);});

导致调用相同的函数,但由于其标签不同而使它们独立延迟

凯泡芙JinJin2020/03/11 20:34:55

您还可以查看underscore.js,它提供了debounce之类的实用方法

var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);