【问题标题】:How do we observe distribution changes on a v0 shadow root?我们如何观察 v0 影子根上的分布变化?
【发布时间】:2016-11-30 04:47:07
【问题描述】:

在 v1 影子根中,我们可以在 <slot> 元素上监听 slotchange,然后使用 slot.assignedNodes() 来检测变化。我正在寻找一种使用 v0 影子根的方法。

使用 ShadowDOM v0,有没有办法观察影子根中 <content> 元素的分布式节点的变化?

实现这一点的最简单方法是使用requestAnimationFrame 创建一个轮询循环,该循环调用content.getDistributedNodes() 将新结果与旧结果进行比较,但显然轮询并不理想而且成本很高。

怎么做?

【问题讨论】:

  • 你能在content元素上使用突变观察器吗?
  • @KevBot 我该怎么做? childList 观察孩子,但分布式节点呢?有例子吗?
  • 可能使用.getDistributedNodes() 方法,并且可以从那里调用这些元素的突变观察者。或者可能在插入点.getDestinationInsertionPoints() 上附加一个突变观察者。我会在早上尝试更具体的工作。
  • 关于为什么这被否决的任何背景?
  • @KevBot,我想了想:对于我们希望观察的给定内容元素,我们可以从它向上遍历找到影子根主机,然后在主机上使用 MutationObserver 来检测孩子的变化,每当发生这种情况时,我们只需在内容元素上调用.getDistributedNodes 以找到新的分布。我们还需要在所有宿主子节点上使用 MutationObserver 来检测属性变化,因为这会导致根的 <content> 元素的选择器结果发生变化。

标签: javascript web-component shadow-dom


【解决方案1】:

在你做的时候,我也需要这个确切的东西。我最终为此创建了一个库,我已经在测试中使用了一周左右。该库称为content-change。它对我来说效果很好,但我相信还有很多改进的机会。

它是这样工作的;类似于 Shadow DOM v1 中的 slot 元素的 slotchange 事件:

// Because this is non-spec, specify internally which components get to be watched
// "this" is the host element
ContentChange.watch(this);

const contentElement = shadow.querySelector('someContentSelector');
contentElement.addEventListener('contentchange', e => {
    // React to distributed node changes for this content element
});

返回给侦听器的event 包含event.details 中的几种不同类型。 event.details.type 将是三个之一:

  • "nodesAdded"
  • "nodesRemoved"
  • "mutation"

允许您对不同的场景做出反应。例如,当添加到主机元素的节点满足分发到该内容元素的要求时,您将收到以下信息:

{
    "type": "nodesAdded",
    "nodesAdded": [Nodes] // An array of newly distributed nodes
}

【讨论】:

  • 酷!很好的实施。我也在考虑这些思路,在主机上使用 MutationObserver,但是对于我的实现部分,这将等同于您的 discoverAddedAndRemovedNodes 我正在考虑运行与 <content> 元素关联的查询以发现哪个主机中的元素匹配,但您使用 getDistributedNodes 的方法更简洁。即,您在 MutationObserver 更改上使用 getDistributedNodes,这与我在原始帖子中考虑在动画帧轮询循环中使用 getDistributedNodes 不同。
  • 顺便问一下,对以下问题有什么想法吗? stackoverflow.com/questions/40004064 我认为这会很好,因为我想观察主机上的分布变化,但我没有创建主机,所以我不知道它们是使用 v0 还是 v1 插槽。一旦我检测到这一点,我就可以在 v0 根目录上使用您的内容更改库。 :D
  • @trusktr 是的,我实际上是在尝试找出可以从主机分发哪些元素以及来自内容元素的所有规则的路径。但最终发生的情况是,如果内容元素没有使用选择器,或者将 * 作为选择器,那么它会分发 textNodes(如您所知)。那些 textNodes 真的很难使用。无论如何,我会看看另一个问题,看起来很有趣。
  • 感谢其他答案。效果很棒。我很快就会尝试你的库。 :D
  • @trusktr,不客气。很高兴这对你有用。
猜你喜欢
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 2017-04-25
  • 2017-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多