封闭影子根内的沙盒事件

问题描述 投票:0回答:1

我的文档中有一个封闭的影子根,它表示包含敏感信息的自定义控件,但是似乎(尽管已关闭)事件仍会从影子根冒出到封闭的 DOM 中,尽管影子根路径被删除一次退出。

这仍然允许信息从封闭的影子 DOM 泄漏到所属文档中,足以说明它鼓励了旨在沙箱化的 DOM 的键盘记录。

Event
对象上存在一个称为
Event.composed
的属性,其中指出:

Event 接口的只读

composed
属性返回一个布尔值,指示事件是否将穿过影子 DOM 边界传播到标准 DOM。

...这正是我所需要的 - 然而是只读的,所以在这方面没有太多帮助。

我尝试过的事情:

  • 删除
    Event.prototype.composed
    并将其替换为
    false
    getter。
  • 影子根的所有者元素上的处理程序并杀死那里的任何事件,但无论我尝试什么,似乎
    document.addEventListener("keydown", e => console.log(e), true);
    都会抓住一个逃亡者,或者我尽早杀死该事件,没有其他人能得到它。

我可以尝试的事情:

  • 劫持
    EventTarget.addEventListener
    方法并将每个回调包装在一些沙箱代码中,以拒绝试图逃离影子根的事件......尽管我不能相信它在任何地方都能工作
  • 劫持每个事件并使用
    composed
    标志
    false
    重新发出它 - 或者作为此处描述的自定义事件...尽管这会导致鼠标或陀螺仪事件的性能下降。
  • iframe 而不是影子根...但我真的不能相信它可以在文档仍然是其所有者的情况下工作。

Javascript 中是否有任何可靠的 高性能方法来防止事件逃离封闭的影子根?任何帮助将不胜感激

javascript dom-events sandbox shadow-dom
1个回答
0
投票

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(默认)事件

escapingshadowDOM

你没有说

如何你试图杀死事件。

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

    

© www.soinside.com 2019 - 2024. All rights reserved.