使用 MutationObserver 检测 scrollHeight 的变化?

Tho*_*der 13 mutation-observers

如何使用 检测scrollHeightDOM 元素的更改时间MutationObserver?它不是属性,也不是数据。

背景:我需要检测滚动条何时出现在我的内容元素上,overflow-y其设置为自动。我认为滚动条出现的那一刻,值就会scrollHeight从 0 跳到 500,所以我的想法是设置 aMutationObserver来检测此属性的变化。

到目前为止我所得到的:

HTML

<div class="body" #body>
Run Code Online (Sandbox Code Playgroud)

CSS

.body {
    overflow-y: auto;
}
Run Code Online (Sandbox Code Playgroud)

打字稿

export class MyWatchedContent implements AfterViewInit, OnDestroy {
   @ViewChild('body', { read: ElementRef })
   private body: ElementRef;

   private observer: MutationObserver;

   public ngAfterViewInit() {
       this.observer = new MutationObserver(this.observerChanges);
       this.observer.observe(this.body.nativeElement, {
           attributes: true,
       });
   }

   public ngOnDestroy() {
       this.observer.disconnect();
   }

   private observerChanges(records: MutationRecord[], observer: MutationObserver) {
       console.log('##### MUTATION');
       records.forEach((_record) => {
           console.log(_record);
       });
   }
}
Run Code Online (Sandbox Code Playgroud)

例如,如果我在开发人员窗口中更改背景颜色,我可以看到观察者正在触发

突变

my-content-watcher.component.ts?d0f4:233 MutationRecord {type: "attributes", target: div.body, addedNodes: NodeList(0), removedNodes: NodeList(0), previousSibling: null ...}

但是,如果我更改窗口大小以显示滚动条,则不会检测到任何突变。这完全可行MutationObserver吗,如果可以,怎么做?

Phi*_*ipp 5

这是答案,对于仍在寻找解决方案的任何人:

截至今天,无法直接监控元素的 scrollHeight 变化。

  • 该MutationObserver检测DOM树,这可能表明scrollHeight属性变化而变化,但是这是一个疯狂的猜测。
  • 所述ResizeObserver检测中的元件的外部高度的变化,而不是scrollHeight属性(即“内”高度)。
  • 目前还没有ScrollHeight-Observer。

但解决方案非常接近:

解决方案

ResizeObserver 检测元素外部高度的变化......

观察滚动容器没有意义,因为它的外部高度不会改变。改变它们的高度的元素是容器的任何 CHILD 节点!

一旦子节点的高度发生变化,就意味着父容器的scrollHeight发生了变化。

香草JS版本

const container = document.querySelector('.scrollable-container');

const observer = new ResizeObserver(function() {
    console.log('New scrollHeight', container.scrollHeight);
});

// This is the critical part: We observe the size of all children!
for (var i = 0; i < container.children.length; i++) {
    observer.observe(container.children[i]);
})
Run Code Online (Sandbox Code Playgroud)

jQuery 版本

const container = $('.scrollable-container');

const observer = new ResizeObserver(function() {
    console.log('New scrollHeight', container[0].scrollHeight);
});

container.children().each(function(index, child) {
    observer.observe(child);
});
Run Code Online (Sandbox Code Playgroud)

进一步的步骤

当动态添加子项时,您可以添加 MutationObserver 以在添加新子项后将其添加到 ResizeObserver。

  • 可笑的是,我们没有一种本地方法可以在 2023 年检查这一点。 (4认同)
  • 元素可能具有动态内容,这意味着子元素可以动态添加/删除。最好将 `ResizeObserver` 与 `MutationObserver` 结合使用,以涵盖内部内容更改和容器实际大小调整的所有情况 (2认同)