问题描述
我有一个仪表板站点,用户可以通过在站点窗口上的任意位置按“ l”或“ g”热键在列表视图或网格视图之间切换。由于此事件侦听器是在整个窗口的“ keydown”事件上调用的,因此,如果用户在网站上的搜索文本框中键入内容时输入“ l”或“ g”,则会导致网站切换视图的问题。
为缓解此问题,我的方法是在“ keydown”元素的搜索文本框元素上添加一个eventListener,以删除window元素上“ keydown”的eventListener。然后,我实现了一个计时器,该计时器在用户停止键入后开始倒计时3秒钟(通过在搜索文本框中添加“ keyup”事件的eventListener)。
经过3秒而未在搜索文本框上触发“ keydown”事件的情况下,然后我再次将“ keydown” eventListener添加回window元素。
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'eventListener成功触发(并且计时器通过在3秒后执行finishTyping函数来按预期工作)。但是,对于搜索框上的'keydown'事件监听器,它并没有删除window元素上的eventListener,我仍然无法找到原因。
解决方法
解决此问题的更简洁的方法可能是使用搜索文本框focus和blur事件,而不是按键输入计时器。
以下示例在您将焦点放在输入元素上时删除了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" />