Idiomatic jQuery delayed event (only after a short pause in typing)? (aka timewatch/typewatch/keywatch)
Solution 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.
Solution 2
Have a look at the excellent Text Change Event plugin from Zurb, purveyors of the highest quality jQuery goods.
Kzqai
I make a ninja game at ninjawars.net, am hirable at bitlucid.com, do art & origami when I can at dnaexmosn.deviantart.com, and code open source stuff on github at github.com/tchalvak Code in: node react php javascript python (some) html/css Learning currently: Css-grid npm packaging aka Tchalvak
Updated on June 02, 2022Comments
-
Kzqai about 2 years
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?