Idiomatic jQuery delayed event (only after a short

2019-01-16 03:25发布

问题:

Here is some jQuery for a search box that I expect is actually an antipattern, and am sure there is a much better solution for that I would love to be pointed towards:

I will describe it in comments then just give the code, since the comments may be more clear and simple than the code:

  • // set up a function call on keypress.
  • // function call has a delay before the main event occurs.
  • // When keypress function is called, wipe any previously queued events and make a new one at the standard delay rate.
  • // Use a global to store the setTimeout pointer.
  • // clearTimeout any pre-existing pointers.
  • // Start a new delay.

The Code:

                // set up a filter function call on keypress.
                $('#supplier-select-filter').keypress(function (){
                    // Currently, resets a delay on an eventual filtering action every keypress.
                    filterSuppliers(.3, this);
                });

                // Delayed filter that kills all previous filter request.
                function filterSuppliers(delay, inputbox){
                    if(undefined != typeof(document.global_filter_trigger)){
                        clearTimeout(document.global_filter_trigger);
                        // clearTimeout any pre-existing pointers.
                    }
                    // Use a global to store the setTimeout pointer.
                    document.global_filter_trigger = setTimeout(function (){
                        var mask = $(inputbox).val();
                        $('#user_id').load("supplier.php?action=ajax_getsuppliers_html&mask="+escape(mask)); 
                    }, 1000*delay); 
                    // Finally, after delay is reached, display the filter results.             
                }

The problems:

On an input box where a search term may consist of 10 characters on average, that's 10 calls to setTimeout in a half a second, which seems to be processor heavy, and in my testing is causing some noticeable performance issues, so hopefully there's a cleaner alternative?

.load() is simpler than taking in JSON and then generating html from the json, but maybe there is a better tool?

.keypress() doesn't seem to always trigger on things like backspace deletion and other essentials, so perhaps using keypress() on this input box isn't the ideal?

回答1:

I frequently use the following approach, a simple function to execute a callback, after the user has stopped typing for a specified amount of time::

$(selector).keyup(function () {
  typewatch(function () {
    // executed only 500 ms after the last keyup event.
  }, 500);
});

Implementation:

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

I think this approach is very simple, and it doesn't imply any global variables.

For more sophisticated usages, give a look to the jQuery TypeWatch Plugin.



回答2:

Have a look at the excellent Text Change Event plugin from Zurb, purveyors of the highest quality jQuery goods.



回答3:

This is a more good way to do it, without using the plugin:

var timeout;
$('input[type=text]').keypress(function() {
if(timeout) {
    clearTimeout(timeout);
    timeout = null;
}

timeout = setTimeout(myFunction, 5000)
})