我正在制作一个虚拟键盘,通过按一个物理键,它的副本必须在屏幕上突出显示.问题是,当我按下按钮时,什么都没有发生.程序侦听鼠标事件,这部分很好.代码提取:

_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;
    },

推荐答案

您必须将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个事件侦听器中添加大约document多个事件侦听器并不是一个好主意.您应该在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');
});

Javascript相关问答推荐

创建私有JS出口

为什么我达到了时间限制!?LeetCode链接列表循环(已解决,但需要解释!)

TypScript界面中的Infer React子props

了解Node.js中的EventEums和浏览器中的addEventEums之间的关系

格式值未保存在redux持久切片中

如何从调整大小/zoom 的SVG路径定义新的d属性?""

从Node JS将对象数组中的数据插入Postgres表

数字时钟在JavaScript中不动态更新

用于编辑CSS样式的Java脚本

映射类型定义,其中值对应于键

使用getBorbingClientRect()更改绝对元素位置

类构造函数忽略Reaction Native中的可选字段,但在浏览器中按预期工作

Puppeteer上每页的useProxy返回的不是函数/构造函数

如何限制显示在分页中的可见页面的数量

try 将Redux工具包与MUI ToggleButtonGroup组件一起使用时出错

将多个文本框中的输出合并到一个文本框中

如何通过Axios在GraphQL查询中发送数组

我不知道如何纠正这一点.

为什么我的Navbar.css没有显示在本地主机页面上?

使用Perl Selify::Remote::Driver执行Java脚本时出错