我有一个带有阴影DOM的自定义元素,该元素侦听属性target
的变化。
target
应该是应该附加我的组件的元素的ID。
我尝试使用querySelector
和getElementById
来获取外部DOM的元素,但它总是返回null
。例如:
console.log(document.getElementById(target));
console.log(document.querySelector('#' + target));
以上两者均返回null。
有没有一种方法可以从影子DOM中获取对父文档中元素的引用?
答案 0 :(得分:0)
如果目标应该是ID,则
document.getElementById(target)
是通过id获取元素的正确代码。其他代码
document.querySelector(target)
不正确,正确的版本应该是
document.querySelector("#" + target)
第一个结果就是您得到null
的事实意味着document
中没有指定的id
标签。如果已经存在,它可能已经被更改/删除,或者您可能想获取另一个页面的标签的ID。
答案 1 :(得分:0)
您只需致电 ShadowRoot 。
this.shadowRoot.getElementById('target')
应该可以工作。
这里是一个示例,get语法会将对象属性绑定到函数。
get target() {
return this.shadowRoot.getElementById('target');
}
答案 2 :(得分:0)
据我所知,shadow DOM 有两个用例:
您控制 shadow DOM 仅通过您的托管自定义元素(如@Penny Liu 的回答)。如果您想确保没有其他脚本应该调用和更改节点,这是您的选择。很确定一些银行网站使用这种方法。不过你放弃了灵活性。
出于样式原因,您只想限定代码的某些部分的范围,但您喜欢通过 document.getElementById 控制它比您可以使用 <slot>
。毕竟,许多库都依赖于 document 对象,而无法在 shadow DOM 中工作。
回到问题,你可能做了这样的事情:
shadowRoot.innerHTML = `...<script>document.getElementById('target')</script>`
// or shadowRoot.appendChild
这不起作用!这也不是预期的 shadow DOM 的工作方式。
回顾方法 2,您应该仅使用 <slot>
标签填充您的 shadow DOM。最简单的例子:
<!-- Custom Element -->
<scoped-playground>
<style>some scoped styling</style>
<div id="target"></div>
<script>const ☝☝☝☝ = document.getElementById('target')</script>
</scoped-playground>
<!-- Scoped playground has a shadowRoot with a default <slot> -->
...
this.shadowRoot.innerHTML = "<slot>Everything is rendered here</slot>";
...
可以在以下位置找到更高级的 <slot>
示例:
https://developers.google.com/web/fundamentals/web-components/shadowdom#composition_slot