问题描述
这个问题的一个非常简单的例子是我为我的新网站 <foot-note>
创建的 fanaro.io 自定义网络组件。
通常,似乎对页内链接有效的是为特定元素创建和 id
,然后将 <a>
与 href="#id_name"
结合使用。但是,当元素位于 shadowRoot
内时,这似乎不起作用,URL 链接仍然正确附加,但没有任何反应。使用 document.querySelector("#id_name");
似乎也不起作用。您可以点击 any of my articles 上的任何 <sup>
脚注,然后使用检查来检查。
这是 Web Components 的限制还是我在这里遗漏了什么?如果我希望进行页内链接,我是否必须最终放弃 Web 组件?或者添加自定义 onClick
方法?
问题已经解决,提交4d2ef0d4fb5c8fe56c76d60eb7274c85bae81d94
前可以找到。它也在 this issue
解决方法
它不是 Web 组件的限制,它是 shadowDOM 的工作原理。
片段标识符通过 ID 引用起作用,因此它们仅在“主”DOM 中起作用,而不在 shadowDOM 中起作用(并且不在 IFRAME 中)。
document.querySelector( )
也无法访问 shadowDOM 中的那些 ID,因为 shadowDOM 的本质是隔离内容。
所以你要么:
- 不要使用 shadowDOM,你真的需要 shadowDOM 功能吗?
该样式应该是全局 CSS 设置,如果您不使用 shadowDOM - 使用 shadowDOM 从每个元素注册一个文档点击侦听器,它会检查片段标识符是否在其 shadowDOM 范围内
因为自定义元素可以访问它的宿主,而 IFRAME 不能
此事件模型最适合带有 shadowDOM 的解耦组件
- 编写一些更复杂的代码,从主 DOM 中调用所有
<foot-note>
[...document.querySelectorAll("foot-note")] .forEach( footnote => footnote.shadowRoot.getElementById(...) )
恕我直言没有您站点中的组件需要 shadowDOM;它会让你的设计更容易,因为你不再有 shadowDOM 范围 CSS,一切都将是全局 CSS
W3C Web Components 标准有 3 个不同的技术
- 模板
- 自定义元素 API
- shadowDOM
每个都可以不用另一个!