Shadow DOM 中的 JavaScript 最佳实践

标签 javascript html web-component shadow-dom

我无法让 JavaScript 在我定义的 Shadow DOM 元素中正常运行。给定以下代码:

<template id='testTemplate'>
 <div id='test'>Click to say hi</div>
 <script>
  var elem = document.querySelector('#test');
  elem.addEventListener('click', function(e) {
     alert("Hi there");
  });
</script>
</template>

<div id="testElement">Host text</div>

<script>
  var shadow = document.querySelector('#testElement').createShadowRoot();
  var template = document.querySelector('#testTemplate');
  shadow.appendChild(template.content.cloneNode(true));
</script>

document.querySelector 返回 null。如果我将它包装在 document.onload 中,它不再抛出错误,但单击 div 也不会启动警报。

  1. 在这种情况下,当我的代码运行时,document.onload 是否是正确的处理方式?
  2. 这是为 shadow dom 元素嵌入 javascript 的正确方法吗?

最佳答案

Shadow DOM 树

您必须将模板标记内的事件处理程序绑定(bind)到 #testElement:

var elem = document.querySelector('#testElement');

含义为原元素/ShadowHost。也就是说,因为来自 ShadowElements 的事件看起来好像是由 ShadowHost 发起的。

Javascript 实际上不在 ShadowDOM-Trees 的范围内。例如,请参阅此博客条目,其中涵盖了该主题:

Remember when I spent all of that time explaining how Shadow DOM CSS was encapsulated and protected from the parent document and how awesome that all was? You might also think that JavaScript works the same way—I did at first—but that’s actually not the case. [...] https://robdodson.me/shadow-dom-javascript/

作为将事件重新安排到 ShadowHost 的解释,作者写道:

This is because events coming from shadow nodes have to be retargeted otherwise they would break encapsulation. If the event target continued to point at #shadow-text then anyone could dig around inside of our Shadow DOM and start messing things up. https://robdodson.me/shadow-dom-javascript/

我认为阅读此博客的其他文章也是个好主意,因为它似乎很好地涵盖了该主题。

自定义元素

使用自定义 HTML 元素,您可以在自定义 HTML 元素内使用 Javascript,例如参见 this answer在 Stackoverflow 上。

基本上您必须创建一个完整的新 HTML 元素。提供教程 at html5rocks .我认为这就是 Polymer 项目提供的方式 its custom events .

关于Shadow DOM 中的 JavaScript 最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25048359/

相关文章:

polymer - 纸张对话框中的自动对焦纸张输入只能工作一次?

javascript - 为什么 Array.from() 返回第一个元素未定义?

javascript - 使用 Meteor 和 React 进行注册确认之前的电子邮件验证

javascript - Dojo 1.4 如何绑定(bind)对象

javascript - 通过 jquery 类隐藏元素

polymer - 如何在 Vaadin 7 应用程序中添加 Vaadin polymer 元素?

angular - 通过父组件以编程方式删除子组件

javascript - Jquery ajax实时验证/超时问题

javascript - 添加文本并将其对齐到自定义 Electron 菜单栏 CSS

jquery - 使用 jQuery 防止点击第二个按钮