编辑1
Firefox 实际上确实将一个事件冒泡到 light DOM,但它是一个 INPUT 事件;不是 CLICK 事件。为什么?
结束编辑1
文档说,在 Shadow DOM 中构成 Web 组件的元素上触发的事件应该从 Shadow DOM 传递到 light DOM,并将目标、currentTarget、originalTarget 等合并到 Web 组件 tagName、id 等中。
在 test_toggle.html 中,我希望收到有关“disTick”复选框上的“单击”事件的通知,以便我可以禁用切换:-
document.getElementById("disTick").addEventListener("click", (e) => {
if (e.target.checked)
myToggle.disabled=true;
else
myToggle.disabled=false;
});
document.body.addEventListener("change", (e) => {console.log("****"+e.target.tagName);});
它可以在 Chrome、Edge、Opera 上调用,但不能在 FireFox 上调用。(我尝试在 BODY 上捕获点击、输入和更改事件,但没有出现任何气泡。)
奇怪的是,我的合成事件确实冒泡了(来自toggle.js)
this.#toggle.addEventListener('keyup', (e) => {
if (e.altKey || e.ctrlKey || e.isComposing || e.metaKey || e.shiftKey)
return;
if (e.keyCode == 32 || e.keyCode == 13)
{
console.log("key = " + e.keyCode);
e.preventDefault();
this.#toggle.click();
}
});
我错过了什么/为什么原始点击没有通过 FireFox 上的 light DOM 冒泡?
您无法在
constructor
中对尚未在 DOM 中的元素设置 DOM/属性:你会得到臭名昭著的错误:
未捕获的 DOMException:无法构造“CustomElement”:结果不得具有属性
late
在下面的代码中,在解析 DOM 之前定义的 Web 组件将失败。
使用 document.createElement( "my-component2" )
时出现同样的错误
参见:通过createElement创建WebComponent
DOM 交互进入 connectedCallback
<script>
const BaseClass = class extends HTMLElement {
constructor() {
super()
.attachShadow({mode: "open"})
.innerHTML = "<style>:host([title]){background:lightgreen}</style>" +
"Hello Web Component " + this.nodeName + " " + this.title;
this.setAttribute("title", "error");
}
};
customElements.define("my-component1", class extends BaseClass {})
</script>
<my-component1 title="foo"></my-component1>
<my-component2 title="bar"></my-component2>
<script>
customElements.define("my-component2", class extends BaseClass {})
</script>