有没有办法阻止影子 dom 内的 javascript 访问影子外的 DOM?
Is there a way to prevent javascript within a shadow dom from accessing the DOM outside of it?
所以如果我有:
js可以改变component_test_div
中的文字
我可以阻止吗?
脚本不受影子保护DOM
Shadow DOM 仅保护 CSS 泄漏或干扰 shadowRoot 的内容。它不会为 JavaScript.
创建新的命名空间
在这段代码中,我在影子根目录中有一些 JS:
class MyEl extends HTMLElement {
constructor() {
super();
this.attachShadow({mode:'open'});
let s = document.createElement('script');
s.textContent = "function dog() { console.log('Bark, Bark'); }";
this.shadowRoot.appendChild(s);
}
}
customElements.define('my-el', MyEl);
setTimeout(()=>dog(), 2000);
<my-el></my-el>
2 秒后我们调用函数 dog()
并且它起作用了。那是因为,即使这段代码被放置在一个shadowRoot中,它仍然在全局范围内执行。
鉴于无法在 Web 组件中隔离您的 JavaScript,您需要记住它可供其范围内的任何人使用。
如果将代码放在 IIFE 中,则可以防止外部调入。但是仍然没有办法阻止内部调出或操纵作用域外的东西。
确定元素是否在阴影中的替代方法DOM
作为@Angel Politis 回答的替代方法,有一种更简单的方法可以确定某个元素是否在某人的 shadowRoot 中:
function isInShadowDOM(el) {
let ret = false;
if (el.getRootNode) {
doc = el.getRootNode();
ret = (doc !== document);
}
return ret;
}
您可以对您想要保护的元素使用 封闭阴影 DOM。
component_test_div.attachShadow( { mode: "closed" } )
.innerHTML = "READ-ONLY"
app_list.attachShadow( { mode: "closed" } )
.appendChild( script.content )
<div id="component_test_div"></div>
<div id="app_list"></div>
<template id="script">
<script>
console.info( "shadowRoot is", component_test_div.shadowRoot )
component_test_div.textContent = "SHADOWED BY SHADOW DOM"
</script>
</template>
影子根的内容将替换任何初始或更改的文本。
closed 属性 将阻止其他脚本访问 shadow root。
所以如果我有:
js可以改变component_test_div
我可以阻止吗?
脚本不受影子保护DOM
Shadow DOM 仅保护 CSS 泄漏或干扰 shadowRoot 的内容。它不会为 JavaScript.
创建新的命名空间在这段代码中,我在影子根目录中有一些 JS:
class MyEl extends HTMLElement {
constructor() {
super();
this.attachShadow({mode:'open'});
let s = document.createElement('script');
s.textContent = "function dog() { console.log('Bark, Bark'); }";
this.shadowRoot.appendChild(s);
}
}
customElements.define('my-el', MyEl);
setTimeout(()=>dog(), 2000);
<my-el></my-el>
2 秒后我们调用函数 dog()
并且它起作用了。那是因为,即使这段代码被放置在一个shadowRoot中,它仍然在全局范围内执行。
鉴于无法在 Web 组件中隔离您的 JavaScript,您需要记住它可供其范围内的任何人使用。
如果将代码放在 IIFE 中,则可以防止外部调入。但是仍然没有办法阻止内部调出或操纵作用域外的东西。
确定元素是否在阴影中的替代方法DOM
作为@Angel Politis 回答的替代方法,有一种更简单的方法可以确定某个元素是否在某人的 shadowRoot 中:
function isInShadowDOM(el) {
let ret = false;
if (el.getRootNode) {
doc = el.getRootNode();
ret = (doc !== document);
}
return ret;
}
您可以对您想要保护的元素使用 封闭阴影 DOM。
component_test_div.attachShadow( { mode: "closed" } )
.innerHTML = "READ-ONLY"
app_list.attachShadow( { mode: "closed" } )
.appendChild( script.content )
<div id="component_test_div"></div>
<div id="app_list"></div>
<template id="script">
<script>
console.info( "shadowRoot is", component_test_div.shadowRoot )
component_test_div.textContent = "SHADOWED BY SHADOW DOM"
</script>
</template>
影子根的内容将替换任何初始或更改的文本。 closed 属性 将阻止其他脚本访问 shadow root。