javascript - 使用 Shadow Root 和原生 Web 组件的页面内链接
这个问题的一个非常简单的例子是我为我的新网站 fanaro.io 创建的 <foot-note> 自定义网页组件。
通常,对于页面内链接而言,有效的方法是为特定元素创建一个 id,然后使用带有 href="#id_name" 的 <a> 标签。然而,当这些元素位于 shadowRoot 中时,这种方法似乎不起作用,URL 链接仍然会正确附加,但没有任何反应。使用 document.querySelector("#id_name"); 似乎也不起作用。你可以点击我任意文章中的任何 <sup> 注脚,然后使用检查工具来查看这个问题。
这是 Web 组件的限制,还是我遗漏了什么?如果我想进行页面内链接,是否必须放弃使用 Web 组件?还是需要添加自定义的 onClick 方法?
该问题已经解决,可以在提交
4d2ef0d4fb5c8fe56c76d60eb7274c85bae81d94之前找到。它也在此问题中有链接
答案#1
这不是Web组件的限制,而是shadowDOM的工作方式。
一个片段标识符通过 ID 引用来工作,因此它们只在“主”DOM 中有效,而不在 shadowDOM(也不在 IFRAME 中)有效。
document.querySelector( ) 也无法访问 shadowDOM 中的那些 ID,因为 shadowDOM 的本质是隔离内容。
所以你要么:
不要使用 shadowDOM,你真的需要 shadowDOM 的功能吗?
- 从每个带有 shadowDOM 的元素注册文档点击监听器,检查 片段标识符 是否在其 shadowDOM 范围内
因为自定义元素可以访问它的宿主,而 IFRAME 无法访问
这种事件模型是带有 shadowDOM 的解耦组件的最佳选择 编写一些更复杂的代码,从主 DOM 中调用所有
<foot-note>[...document.querySelectorAll("foot-note")] .forEach( footnote => footnote.shadowRoot.getElementById(...) )
该样式应该是全局 CSS 设置,如果你 不 使用 shadowDOM,则会应用
依我看,你网站中的没有一个组件需要 shadowDOM;这样你的设计会更简单,因为你不再有shadowDOM 范围的 CSS,所有的都会是全局 CSS
W3C Web 组件标准有3种不同的技术
- 模板
- 自定义元素 API
- 影子DOM
每一个都可以独立使用!
