我找到了 this WPT测试中的特定测试:
<script>
function myObserver(mutationsList) {
for (let mutation of mutationsList) {
for (let n of mutation.addedNodes) {
if (n.id === 'shadow') {
n.innerHTML = "<span id=replaced>This should be in <div>'s shadow root</span>";
}
}
}
}
var observer = new MutationObserver(myObserver);
observer.observe(document.body, { childList: true, subtree: true });
</script>
<div id=host>
<template id=shadow shadowroot=open>
<span id=toreplace>This should get removed</span>
<script></script> <!-- Ensure observer runs -->
</template>
</div>
现在问题是关于 <script></script> <!-- Ensure observer runs -->
-> 这行代码如何确保观察者运行?
最佳答案
Running a script确实触发了 cleanup after running a script步骤,它本身确实会强制执行 microtask-checkpoint观察者的通知将被发送到哪里。
我的猜测是他们在这里使用它来强制在 <template>
之前发出这些突变通知。标记已关闭,正如测试名称“innerHTML before closing tag”所暗示的那样。
然而,如果我的猜测是正确的,我相信这段代码实际上是错误的:
如果 <script>
,所有浏览器都不会运行脚本标签完全是空的,在 Firefox 中,它至少需要一些文本内容才能运行所有这些步骤,从而强制执行微任务检查点。即使是空格字符也可以,但这是必要的,如下面的代码片段所示:
使用完全空的 <script></script>
,我们在 Firefox 中看到当整个元素已经被解析时观察者运行。
<script>
function myObserver(mutationsList) {
for (let mutation of mutationsList) {
for (let n of mutation.addedNodes) {
if (n.id === 'parent') {
console.log([...n.children].map(el => el.outerHTML));
}
}
}
}
var observer = new MutationObserver(myObserver);
observer.observe(document.body, { childList: true, subtree: true });
</script>
<div id=parent>
<span id=child>This should be in the log.</span>
<script></script><!-- forces the observer to run -->
<span id=sibling>This should not be in the log</span>
</div>
运行相同的代码片段,但在 <script> </script>
中只包含一个空格字符,我们看到观察者在 <script>
之后运行已被解析,在“兄弟”<span>
之前有。
<script>
function myObserver(mutationsList) {
for (let mutation of mutationsList) {
for (let n of mutation.addedNodes) {
if (n.id === 'parent') {
console.log([...n.children].map(el => el.outerHTML));
}
}
}
}
var observer = new MutationObserver(myObserver);
observer.observe(document.body, { childList: true, subtree: true });
</script>
<div id=parent>
<span id=child>This should be in the log.</span>
<script> </script><!-- forces the observer to run -->
<span id=sibling>This should not be in the log</span>
</div>
我打开了an issue on WPT让 Mason Freed 或那里的任何其他人查看并确认我的假设,并在需要时修复这些测试。
关于javascript - <script> 标签如何强制 MutationObserver 在 Declarative Shadow DOM 中提前运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73283986/