Shadow DOM 中的 JavaScript 最佳实践
-
21-12-2019 - |
题
我无法让 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 的正确方法吗?
解决方案
影子 DOM 树
您必须将 eventHandler 绑定到模板标记内 #testElement
:
var elem = document.querySelector('#testElement');
含义为原始元素/ShadowHost。也就是说,因为来自 ShadowElements 的事件看起来好像是由 ShadowHost 发起的。
Javascript 实际上并不在 ShadowDOM-Trees 内部。例如,请参阅此博客文章,其中涵盖了该主题:
还记得我花了所有时间解释 Shadow DOM CSS 是如何封装并保护其免受父文档影响的吗?这一切是多么棒?你可能还认为 JavaScript 的工作方式是一样的——我一开始也是这么做的——但事实并非如此。[...] http://robdodson.me/blog/2013/09/02/shadow-dom-javascript/
作为重新安排 ShadowHost 事件的解释,作者写道:
这是因为 来自影子节点的事件必须重新定位,否则它们会破坏封装。 如果事件目标继续指向
#shadow-text
然后任何人都可以在我们的 Shadow DOM 内部挖掘并开始搞砸事情。 http://robdodson.me/blog/2013/09/02/shadow-dom-javascript/
我认为阅读该博客的其他文章也是个好主意,因为它似乎很好地涵盖了该主题。
自定义元素
通过自定义 HTML 元素,您可以在自定义 HTML 元素内使用 Javascript,请参见示例 这个答案 在 Stackoverflow 上。
基本上您必须创建一个全新的 HTML 元素。有教程可用 在 html5rocks. 。我认为这就是 Polymer 项目提供的方式 它的自定义事件.