我搜索了一段时间;但只能找到聚合物的答案;
或将 EventListener 放置在 ShadowRoot 内的 DOM 元素上的答案。
我试图使用 native 自定义元素实现的效果:
- 只有获得焦点的元素才应接受(并显示)按键
可以将点击事件附加到shadowRoot,看来我对“keyup”事件做了一些错误的事情。
如果我将 EventListener
放在窗口
上,所有元素(当然)都会使用相同的关键信息进行更新。
window.customElements.define('game-toes', class extends HTMLElement {
constructor() {
super().attachShadow({mode:'open'})
.innerHTML = this.tabIndex;
this.addEventListener('keyup',evt=>this.shadowRoot.innerHTML = 'key:'+evt.key);
}
});
game-toes{
display:inline-block;
height:auto;
width:100px;
padding:1em;
border:10px solid green;
}
game-toes:focus {
background-color: lightgreen;
}
<game-toes tabindex=1></game-toes>
<game-toes tabindex=2></game-toes>
<game-toes tabindex=3></game-toes>
最佳答案
您可以像以前一样执行此操作,但需要添加一些额外的代码才能使其工作:
function on(el, evt, cb) {
el.addEventListener(evt, cb);
return () => {
el.removeEventListener(evt, cb);
}
}
window.customElements.define('game-toes', class extends HTMLElement {
constructor() {
super()
.attachShadow({mode: 'open'})
.innerHTML = this.tabIndex;
}
connectedCallback() {
this._offKeyup = on(this, 'keyup', evt => {
this.shadowRoot.innerHTML = evt.key;
evt.stopPropagation(); // Prevent the event from leaving this element
});
}
disconnectedCallback() {
this._offKeyup();
}
});
game-toes{
display:inline-block;
height:auto;
width:100px;
padding:1em;
border:10px solid green;
}
game-toes:focus {
background-color: lightgreen;
}
<game-toes tabindex=1></game-toes>
<game-toes tabindex=2></game-toes>
<game-toes tabindex=3></game-toes>
- 您可能需要使用
evt.stopPropagation()
来阻止事件离开组件。 - 您需要在组件本身上添加事件监听器,或者在 ShadowRoot 中创建一个能够获得焦点的元素,然后在组件获得焦点时将焦点设置在内部元素上。然后您应该能够在该内部元素上添加
keyup
事件。 - 最安全的做法是在
connectedCallback
中添加 eventListener 并在disconnectedCallback
中释放它们,除非您从未打算删除组件。
关于javascript - 如何将 keyup 事件附加到自定义元素shadowRoot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52330155/