【问题标题】:JavaScript within Shadow DOM best practicesShadow DOM 中的 JavaScript 最佳实践
【发布时间】:2014-07-30 23:00:58
【问题描述】:

我无法让 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 的正确方法吗?

【问题讨论】:

    标签: javascript html web-component shadow-dom


    【解决方案1】:

    阴影 DOM 树

    您必须将模板标签内的 eventHandler 绑定到#testElement

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

    对原始元素的含义/ShadowHost。也就是说,因为来自 ShadowElements 的事件看起来好像它们源自 ShadowHost。

    Javascript 实际上不在 ShadowDOM-Trees 内。例如,请参阅此博客条目,它完全涵盖了该主题:

    还记得我花了那么多时间解释 Shadow DOM CSS 是如何被封装并不受父文档影响的,以及这一切有多棒吗?您可能还认为 JavaScript 的工作方式与我最初的做法相同,但实际上并非如此。 [...] https://robdodson.me/shadow-dom-javascript/

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

    这是因为来自影子节点的事件必须重新定位,否则它们会破坏封装。如果事件目标继续指向#shadow-text,那么任何人都可以在我们的 Shadow DOM 内部进行挖掘并开始搞砸了。 https://robdodson.me/shadow-dom-javascript/

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

    自定义元素

    通过自定义 HTML 元素,您可以在自定义 HTML 元素中使用 Javascript,例如参见 Stackoverflow 上的 this answer

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

    【讨论】:

    • 所以如果我理解正确我的问题是模板中的 JavaScript 基本上被视为全局的,所以它唯一可以响应的事件是冒泡的事件,当它们冒泡时被重新定位了吗?
    • 是的。如果不使用自定义元素,我看不到将处理程序绑定到影子 DOM 元素的方法。
    • 我最终通过聚合物使用自定义元素。使整个过程变得更加容易。
    • 第一个链接中的文章已移至https://robdodson.me/shadow-dom-javascript/
    • @nick.amor 谢谢,我更改了网址。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 2013-11-12
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多