脚本标记中断模板标记的突变观察器

Script Tag Interrupts Mutation Observer for Template Tags

提问人:JRJurman 提问时间:9/16/2023 最后编辑:JRJurman 更新时间:9/16/2023 访问量:35

问:

我正在构建一个库,该库与模板标签交互,并监视可能使用 MutationObserver 添加到页面的新标签。

<script>
  const upgradeNewNodes = (mutationRecords) => {
    mutationRecords.forEach((mutationRecord) => {
      mutationRecord.addedNodes.forEach((newNode) => {
        if (newNode.matches?.('template')) {
          console.log([...newNode.content.childNodes].map(child => child.nodeName))
        }
      });
    });
  };

  const observer = new MutationObserver(upgradeNewNodes);
  observer.observe(document, { subtree: true, childList: true });
</script>

<template>
  <span>Beginning</span>
  <script>
    console.log('foo')
  </script>
  <span>Ending</span>
</template>

但是,当我的突变观察者拾取此模板标签时,它最多只能看到脚本标签

// [object NodeList] (4)
[#text,<span/>,#text,<script/>]

Codepen 链接: https://codepen.io/JRJurman/pen/WNLEaqp?editors=1001

我目前的假设是,HTML 解析器在命中 script 标签时会停止。

在我的实际库中,我只能处理一次内容,因此为模板中的内容添加另一个 MutationObserver 并不是一个真正的选择。

有没有办法知道模板何时完全加载?有没有其他方法可以逐步捕获添加到页面的模板标签(除了 MutationObserver)?

JavaScript HTML 突变观察者

评论

0赞 Barmar 9/16/2023
请发布一个最小的可重复示例。您可以使用堆栈代码段使其可执行。这比指向 codepen 的链接更可取。
0赞 wOxxOm 9/16/2023
您可以为模板创建一个新的观察者,它将在脚本之后看到节点。content
0赞 JRJurman 9/16/2023
@Barmar - 更新!:D
0赞 JRJurman 9/16/2023
@wOxxOm - 我会在摘要中更清楚地说明这一点,但在实际程序中,我只能处理一次模板的内容,因此一旦完成,我需要确定,而不是处于部分状态
0赞 JRJurman 9/16/2023
@wOxxOm - 话虽如此,如果您想将其添加为答案,这对其他人来说可能是一个有用的选择!

答:

0赞 JRJurman 9/16/2023 #1

这里的一个潜在选择似乎是在模板标签之后立即监视节点 - 这些节点几乎总是保证存在,因为在元素之前、之间和之后总是有 TEXT 节点。

<script>
  const upgradeNewNodes = (mutationRecords) => {
    mutationRecords.forEach((mutationRecord) => {
      mutationRecord.addedNodes.forEach((newNode) => {
        // check if this node is after a template (if it is, process that template)
        // this is almost always guaranteed to exist, and be a TEXT node
        if (newNode.previousSibling?.matches?.('template')) {
          console.log([...newNode.previousSibling.content.childNodes].map(child => child.nodeName))
        }
      });
    });
  };

  const observer = new MutationObserver(upgradeNewNodes);
  observer.observe(document, { subtree: true, childList: true });
</script>

<template>
  <span>Beginning</span>
  <script>
    console.log('foo')
  </script>
  <span>Ending</span>
</template>

结果:

// [object NodeList] (7)
[#text,<span/>,#text,<script/>,#text,<span/>,#text]

Codepen 链接: https://codepen.io/JRJurman/pen/jOXLQmY?editors=1001