How to delay the .keyup() handler until the user stops typing?

前端 未结 27 2546
半阙折子戏
半阙折子戏 2020-11-21 23:32

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”, “Wi

相关标签:
27条回答
  • 2020-11-21 23:57

    Based on the answer of CMS, it just ignores the key events that doesn't change value.

    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 );
    
    
    })
    
    0 讨论(0)
  • 2020-11-21 23:57

    Well, i also made a piece of code for limit high frequency ajax request cause by Keyup / Keydown. Check this out:

    https://github.com/raincious/jQueue

    Do your query like this:

    var q = new jQueue(function(type, name, callback) {
        return $.post("/api/account/user_existed/", {Method: type, Value: name}).done(callback);
    }, 'Flush', 1500); // Make sure use Flush mode.
    

    And bind event like this:

    $('#field-username').keyup(function() {
        q.run('Username', this.val(), function() { /* calling back */ });
    });
    
    0 讨论(0)
  • 2020-11-21 23:58

    Saw this today a little late but just want to put this here in case someone else needed. just separate the function to make it reusable. the code below will wait 1/2 second after typing stop.

        var timeOutVar
    $(selector).on('keyup', function() {
    
                        clearTimeout(timeOutVar);
                        timeOutVar= setTimeout(function(){ console.log("Hello"); }, 500);
                    });
    
    0 讨论(0)
  • 2020-11-22 00:00

    This is a solution along the lines of CMS's, but solves a few key issues for me:

    • Supports multiple inputs, delays can run concurrently.
    • Ignores key events that didn't changed the value (like Ctrl, Alt+Tab).
    • Solves a race condition (when the callback is executed and the value already changed).
    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)
                }
            }
        }
    }())
    

    Usage:

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

    The code is written in a style I enjoy, you may need to add a bunch of semicolons.

    Things to keep in mind:

    • A unique id is generated based on the form id and input name, so they must be defined and unique, or you could adjust it to your situation.
    • delay returns an object that's easy to extend for your own needs.
    • The original element used for delay is bound to the callback, so this works as expected (like in the example).
    • Empty value is ignored in the second validation.
    • Watch out for enqueue, it expects milliseconds first, I prefer that, but you may want to switch the parameters to match setTimeout.

    The solution I use adds another level of complexity, allowing you to cancel execution, for example, but this is a good base to build on.

    0 讨论(0)
  • 2020-11-22 00:00

    Here is a suggestion I have written that takes care of multiple input in your form.

    This function gets the Object of the input field, put in your code

    function fieldKeyup(obj){
        //  what you want this to do
    
    } // fieldKeyup
    

    This is the actual delayCall function, takes care of multiple input fields

    function delayCall(obj,ms,fn){
        return $(obj).each(function(){
        if ( typeof this.timer == 'undefined' ) {
           // Define an array to keep track of all fields needed delays
           // This is in order to make this a multiple delay handling     
              function
            this.timer = new Array();
        }
        var obj = this;
        if (this.timer[obj.id]){
            clearTimeout(this.timer[obj.id]);
            delete(this.timer[obj.id]);
        }
    
        this.timer[obj.id] = setTimeout(function(){
            fn(obj);}, ms);
        });
    }; // delayCall
    

    Usage:

    $("#username").on("keyup",function(){
        delayCall($(this),500,fieldKeyup);
    });
    
    0 讨论(0)
  • 2020-11-22 00:02

    Delay function to call up on every keyup. jQuery 1.7.1 or up required

    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 );
      });
    }
    

    Usage: $('#searchBox').keyupDelay( cb );

    0 讨论(0)
提交回复
热议问题