javascript - 如何将 keyup 事件附加到自定义元素shadowRoot

标签 javascript dom-events addeventlistener shadow-dom custom-element

我搜索了一段时间;但只能找到聚合物的答案;
或将 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>

  1. 您可能需要使用 evt.stopPropagation() 来阻止事件离开组件。
  2. 您需要在组件本身上添加事件监听器,或者在 ShadowRoot 中创建一个能够获得焦点的元素,然后在组件获得焦点时将焦点设置在内部元素上。然后您应该能够在该内部元素上添加 keyup 事件。
  3. 最安全的做法是在 connectedCallback 中添加 eventListener 并在 disconnectedCallback 中释放它们,除非您从未打算删除组件。

关于javascript - 如何将 keyup 事件附加到自定义元素shadowRoot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52330155/

相关文章:

javascript - addEventListener 的闭包应该放在哪里?

javascript - IE9中的数据问题addEventListener

javascript - 使用 'background-size: contain' 在具有背景的 flexbox 中居中内容

javascript - 如何将事件处理程序分配给自定义元素

javascript - 如何确保两个客户端不会同时请求破坏状态

javascript - 如何对JSON对象进行计数并在计数的基础上取相同的输出

javascript - 如何使用 Javascript 从 URL 获取响应

javascript - addEventListener 到多个元素,使用事件委托(delegate) (JavaScript)

javascript - 我正在尝试运行一个简单的 jqplot 示例,但它不会显示,为什么不呢?

javascript - Ember 显示来自 ajax 调用的数据