I am trying to create a simple debounce for text input. Following is the code:
<body>
<input id="myInput" type="text" />
</body>
<script>
function save(data) {
console.log('saved!!', myInput.value);
}
//function process(e, callback, delay) { signature is changed like this, when we call onKeyUp
function process(callback, delay) { //signature is changed to this, when we call 'process' directly
//console.log('e', e, 'callback', callback, 'delay', delay);
let timer;
return function () {
clearTimeout(timer);
timer = setTimeout(callback, delay);
}
}
function onKeyUp(e) {
//console.log('onKeyUp')
process(e, save, 1000)
}
//const inp = document.querySelector("#txtInput");
const inp = document.getElementById("myInput");
inp.addEventListener(
'keyup',
//process(save, 1000) //works
onKeyUp //-- > does not work
);
</script>
If I simply call process
function on keyup event, it works as expected.
However, I also want to pass e.target.value, and hence I want to event object as well. Hence, to achieve that when I tried calling another function called onKeyUp
, which captures event object and when I pass it to process(e, save, 1000)
the setTimeout isn't getting called and hence save function isn't getting triggered.
My question is what is the difference when we call process
funtion directly on event listener and when we call another function and pass event object to it.
The process(save, 1000)
works because it return a function (the anonymous function returned in process()
) which passes to inp.addEventListener
as the second parameter
inp.addEventListener(
'keyup',
process(save, 1000)
);
// equals to
const callback = process(save, 1000); //get the anonymous function returned in `process()`
inp.addEventListener(
'keyup',
callback
); //callback will be called like callback() when keyup
but when change it to onKeyup
, the anonymous function will not be called, so the setTimeout
won't work, so does the save
function
inp.addEventListener(
'keyup',
onKeyup
); // onKeyup will be called like onKeyup()
function onKeyUp(e) {
process(e, save, 1000) // process called
}
function process(e, callback, delay) {
let timer;
return function () { // not called, it returns as a function only
clearTimeout(timer);
timer = setTimeout(callback, delay);
}
}
To fix it. you can do
function onKeyUp(e) {
process(e, save, 1000)();
}
let timer; //assign the `timer` as a global variable
function process(e, callback, delay) {
return function () {
clearTimeout(timer);
timer = setTimeout(callback, delay);
}
}
More further, you don't need onKeyup
if you just want to get the event
parameter.In the first code, the anonymous function was called when keyup, it accepted the event parameter already.
function process(callback, delay) {
let timer;
return function (e) { // you can get `e` here
clearTimeout(timer);
timer = setTimeout(callback, delay);
}
}