我的文档中有一个封闭的影子根,它表示包含敏感信息的自定义控件,但是似乎(尽管已关闭)事件仍会从影子根冒出到封闭的 DOM 中,尽管影子根路径被删除一次退出。
这仍然允许信息从封闭的影子 DOM 泄漏到所属文档中,足以说明它鼓励了旨在沙箱化的 DOM 的键盘记录。
Event
对象上存在一个称为Event.composed
的属性,其中指出:
Event 接口的只读
属性返回一个布尔值,指示事件是否将穿过影子 DOM 边界传播到标准 DOM。composed
...这正是我所需要的 - 然而是只读的,所以在这方面没有太多帮助。
我尝试过的事情:
Event.prototype.composed
并将其替换为 false
getter。document.addEventListener("keydown", e => console.log(e), true);
都会抓住一个逃亡者,或者我尽早杀死该事件,没有其他人能得到它。我可以尝试的事情:
EventTarget.addEventListener
方法并将每个回调包装在一些沙箱代码中,以拒绝试图逃离影子根的事件......尽管我不能相信它在任何地方都能工作composed
标志 false
重新发出它 - 或者作为此处描述的自定义事件...尽管这会导致鼠标或陀螺仪事件的性能下降。Javascript 中是否有任何可靠的 和 高性能方法来防止事件逃离封闭的影子根?任何帮助将不胜感激
mode:"closed"
MDN 文档:https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/mode
当影子根的模式为“封闭”时,
影子根的实现内部无法从 JavaScript 访问且不可更改,就像元素的实现内部无法从 JavaScript 访问且不可更改一样。
closed
(或“打开”)与事件无关。
composed
MDN 文档:
https://developer.mozilla.org/en-US/docs/Web/API/Event/composed
Event 接口的只读这意味着
composed
属性返回一个布尔值,指示事件是否将穿过影子 DOM 边界传播到标准 DOM。
composed
属性在IN 事件中是只读的。 您可以在自定义事件上设置
composed
来制作your 事件 escape ShadowDOM:
new CustomEvent("myownevent", {
composed: true,
bubbles: true,
});
stop(默认)事件如何你试图杀死事件。
evt.stopPropagation()
完成工作;但你必须把它们全部抓住。
<script>
const element = (tag, props = {}) => Object.assign(document.createElement(tag), props);
const log = (...args) => document.body.append(...args, element("br"));
const listen = (scope, type, label) =>
scope.addEventListener(type, () => log(type, " received event on window"));
listen(window, "click");
listen(window, "keydown");
listen(window, "keyup");
customElements.define("my-component", class extends HTMLElement {
constructor() {
super().attachShadow({mode:"closed"})
.append(
element("input", {
type: "text",
onkeydown: (evt) => log(evt.type, " in input"),
onkeyup: (evt) => log(evt.type, " in input")
}),
element("button", {
innerText: "click me",
onclick: (evt) => log("clicked button")
})
)
}
connectedCallback() {
const stopPropagation = (type) => this[type] = (evt) => {
log("stopPropagation ", evt.type);
evt.stopPropagation();
}
stopPropagation("onclick");
stopPropagation("onkeydown");
}
});
</script>
<my-component></my-component>
<hr>
注意(和吹毛求疵):小心使用我自己的变量名
evt
而不是
event
,因为由于 IE 的历史原因(可以追溯到 20 年前),
event
在所有现代浏览器中仍然是全局
window.event
。你
event
,只要明白你不是传递一个参数而是使用
window.event