输入带有超时的 onKeyUp 事件

input onKeyUp Event with timeout

我正在尝试为文本输入创建一个简单的去抖动。以下是代码:

<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>

如果我只是在 keyup 事件上调用 process 函数,它会按预期工作。

但是,我也想传递 e.target.value,因此我也想传递事件对象。因此,为了实现这一点,当我尝试调用另一个名为 onKeyUp 的函数时,它捕获事件对象,当我将它传递给 process(e, save, 1000) 时,setTimeout 没有被调用,因此保存函数没有被触发。

我的问题是,当我们直接在事件侦听器上调用 process 函数与调用另一个函数并将事件对象传递给它时有什么区别。

process(save, 1000) 之所以有效,是因为它 return 一个函数(return 在 process() 中编辑的匿名函数)作为第二个参数传递给 inp.addEventListener

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

但是改成onKeyup,匿名函数就不会被调用,所以setTimeout就不行了,save函数也是

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

修复它。你可以做到

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

更进一步,你不需要onKeyup如果你只是想得到event parameter.In第一个代码,匿名函数在keyup时被调用,它接受了已有事件参数。

function process(callback, delay) { 
    let timer;
    return function (e) { // you can get `e` here
        clearTimeout(timer);
        timer = setTimeout(callback, delay);
    }
}