Keydown 事件监听器不监听
Keydown Event Listener does not listen
我正在制作一个虚拟键盘,通过按下物理键,它的副本必须在屏幕上突出显示。问题是,当我按下按钮时,绝对没有任何反应。程序监听鼠标事件,这部分没问题。代码提取:
_createKeys() {
const fragment = document.createDocumentFragment();
const layout = [
'`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 'backspace',
'tab', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']',
'caps lock', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '\', 'enter',
'shiftLeft', '\', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 'shiftRight', 'arrowUp',
'Ctrl', 'Win', 'Alt', 'space', 'Alt', 'Ctrl', 'arrowLeft', 'arrowDown', 'arrowRight'
];
const createIconHTML = (icon_name) => {
return `<i class="material-icons">${icon_name}</i>`;
};
layout.forEach(key => {
const keyElement = document.createElement('button');
const lineBreak = ['backspace', ']', 'enter', 'arrowUp'].indexOf(key) !== -1;
keyElement.setAttribute('type', 'button');
keyElement.classList.add('key');
switch(key) {
case 'caps lock':
keyElement.classList.add('key-wide');
keyElement.textContent = 'CapsLock';
keyElement.addEventListener("click", () => {
this._toggleCapsLock();
keyElement.classList.toggle('key-caps', this.properties.capsLock);
});
keyElement.addEventListener('keydown', (e) => {
if(e.key === 'CapsLock') console.log('pressed');
});
}
fragment.appendChild(keyElement);
if (lineBreak) {
fragment.appendChild(document.createElement('br'));
}
});
return fragment;
},
你只调用 switch case 内的 addEventListener
也调用 document
而不是元素,这只发生在大写字母上,所以这需要退出。
另外,既然只有一个 switch
case
,为什么不使用 if 条件呢?会让代码更易读。
您必须将 keydown
事件侦听器添加到 document
而不是 keyElement
否则事件只会在元素具有焦点时触发,如果光标在页面其他地方的文本字段中。
而不是:
keyElement.addEventListener('keydown', (e) => {
if(e.key === 'CapsLock') console.log('pressed');
});
使用:
document.addEventListener('keydown', (e) => {
if(e.key === 'CapsLock') console.log('pressed');
});
但是,向 document
添加 ~100 多个事件侦听器并不是一个好主意。您应该在 document
上创建一个事件侦听器,用于侦听所有按键事件并激活相应的虚拟键。
layout.forEach(key => {
...
keyElement.dataset.key = encodeURIComponent(key);
...
});
document.addEventListener('keydown', event => {
let k = encodeURIComponent(event.key);
let vkey = document.querySelector(`[data-key="${k}"]`);
vkey?.classList.add('pressed');
});
我正在制作一个虚拟键盘,通过按下物理键,它的副本必须在屏幕上突出显示。问题是,当我按下按钮时,绝对没有任何反应。程序监听鼠标事件,这部分没问题。代码提取:
_createKeys() {
const fragment = document.createDocumentFragment();
const layout = [
'`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 'backspace',
'tab', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']',
'caps lock', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '\', 'enter',
'shiftLeft', '\', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 'shiftRight', 'arrowUp',
'Ctrl', 'Win', 'Alt', 'space', 'Alt', 'Ctrl', 'arrowLeft', 'arrowDown', 'arrowRight'
];
const createIconHTML = (icon_name) => {
return `<i class="material-icons">${icon_name}</i>`;
};
layout.forEach(key => {
const keyElement = document.createElement('button');
const lineBreak = ['backspace', ']', 'enter', 'arrowUp'].indexOf(key) !== -1;
keyElement.setAttribute('type', 'button');
keyElement.classList.add('key');
switch(key) {
case 'caps lock':
keyElement.classList.add('key-wide');
keyElement.textContent = 'CapsLock';
keyElement.addEventListener("click", () => {
this._toggleCapsLock();
keyElement.classList.toggle('key-caps', this.properties.capsLock);
});
keyElement.addEventListener('keydown', (e) => {
if(e.key === 'CapsLock') console.log('pressed');
});
}
fragment.appendChild(keyElement);
if (lineBreak) {
fragment.appendChild(document.createElement('br'));
}
});
return fragment;
},
你只调用 switch case 内的 addEventListener
也调用 document
而不是元素,这只发生在大写字母上,所以这需要退出。
另外,既然只有一个 switch
case
,为什么不使用 if 条件呢?会让代码更易读。
您必须将 keydown
事件侦听器添加到 document
而不是 keyElement
否则事件只会在元素具有焦点时触发,如果光标在页面其他地方的文本字段中。
而不是:
keyElement.addEventListener('keydown', (e) => {
if(e.key === 'CapsLock') console.log('pressed');
});
使用:
document.addEventListener('keydown', (e) => {
if(e.key === 'CapsLock') console.log('pressed');
});
但是,向 document
添加 ~100 多个事件侦听器并不是一个好主意。您应该在 document
上创建一个事件侦听器,用于侦听所有按键事件并激活相应的虚拟键。
layout.forEach(key => {
...
keyElement.dataset.key = encodeURIComponent(key);
...
});
document.addEventListener('keydown', event => {
let k = encodeURIComponent(event.key);
let vkey = document.querySelector(`[data-key="${k}"]`);
vkey?.classList.add('pressed');
});