我无法让 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 也不会启动警报。
- 在这种情况下,当我的代码运行时,document.onload 是否是正确的处理方式?
- 这是为 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/