【问题标题】:removeEventListener is not executing on 'keydown' eventremoveEventListener 未在“keydown”事件上执行
【发布时间】:2020-11-12 10:36:09
【问题描述】:

我有一个仪表板站点,用户可以通过在站点窗口的任意位置按“l”或“g”热键在列表视图或网格视图之间切换。由于这个 eventListener 在整个窗口的 'keydown' 事件上被调用,这会导致如果用户在网站上的搜索文本框中输入“l”或“g”,网站将切换视图的问题。

为了缓解这个问题,我的方法是在搜索文本框元素上为“keydown”元素添加一个 eventListener,删除窗口元素上“keydown”的 eventListener。然后我实现了一个计时器,它在用户停止输入后开始倒计时 3 秒(通过在搜索文本框上为“keyup”事件添加一个 eventListener)。

3 秒后没有在搜索文本框上触发 'keydown' 事件,然后我再次将 'keydown' eventListener 添加回窗口元素。

JS 代码

let timer;
let timeInterval = 3000; // milliseconds so equates to 3 seconds

let searchTextBox = document.querySelector("#search-textbox");

if (typeof (searchTextBox) != 'undefined' && searchTextBox != null) { // check if the search text box was successfully created and inserted into the DOM
    searchTextBox.addEventListener('keydown', function () { // when key is pressed on the search text box, remove the window eventListener
        window.removeEventListener('keydown', addViewHotKeys);
    });

    searchTextBox.addEventListener('keyup', function () { // start the timer after a key is released
        console.log('key lifted');
        clearTimeout(timer); // clear the timeout if it was already set
        if (searchTextBox.value) { // if the textbox has any input inside, set the timer to execute the finishedTyping function after the timeInterval milliseconds has elapsed
            timer = setTimeout(finishedTyping, timeInterval);
        }
    });

    function finishedTyping() {
        addViewHotKeys();
        console.log('times up');
    }
}

// Detect hotkeys for easy navigation on index.html
function addViewHotKeys() {
    window.addEventListener('keydown', function (event) {
        if (event.key === 'l') {
            if (state.display !== 'list') {
                state.display = 'list';
                renderViewSelection();
                renderDashboardPlane();
            }
        } else if (event.key === 'g') {
            if (state.display !== 'grid') {
                state.display = 'grid';
                renderViewSelection();
                renderDashboardPlane();
            }
        }
    });
}

window.addEventListener('load', function () {
    addViewHotKeys();
});

我在搜索文本框上的 'keydown' 和 'keyup' eventListeners 成功触发(并且计时器通过在 3 秒后执行 finishedTyping 函数按预期工作)。但是,对于搜索框上的“keydown”事件监听器,它并没有删除窗口元素上的事件监听器,我仍然无法找到原因。

【问题讨论】:

    标签: javascript textbox addeventlistener


    【解决方案1】:

    解决此问题的更简洁的方法可能是使用搜索文本框 focusblur 事件,而不是按键输入的计时器。

    以下示例在您关注输入元素时移除 keydown 事件侦听器,并在输入元素失去焦点时再次添加它。您可以应用相同的技术来包含任何其他输入元素。

    let searchTextBox = document.querySelector("#search-textbox");
    
    // Detect hotkeys for easy navigation on index.html
    function addViewHotKeys(event) {
      if (event.key === 'l') {
        console.log('l');
        
        // useful code here
        
      } else if (event.key === 'g') {
        console.log('g');
        
        // useful code here
      }
    }
    
    window.addEventListener('load', function () {
        searchTextBox.addEventListener('focus', function() {
            window.removeEventListener('keydown', addViewHotKeys);
        });
        
        searchTextBox.addEventListener('blur', function() {
            window.addEventListener('keydown', addViewHotKeys);
        });
        
        window.addEventListener('keydown', addViewHotKeys);
    });
    <p>Press the l or g key to log that letter to the console, except when the input has focus:</p>
    <input id="search-textbox" type="search" value="" placeholder="search-textbox" />

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-28
      • 2012-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-14
      相关资源
      最近更新 更多