Skip to content

DOM 观察

IntersectionObserver

用于监听目标元素与视口(viewport)的交叉状态,常用于实现懒加载、无限滚动等功能。

js
const observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      console.log('元素进入视口')
    }
  })
})

observer.observe(document.querySelector('.target-element'))

实例属性

  • root:指定观察的根元素,默认为 document 视口。
  • rootMargin:用于扩展或收缩 root 的边界(类似 CSS margin)。
  • thresholds:触发回调的可见比例数组。

实例方法

  • disconnect():停止观察 所有目标元素
  • observe():开始观察指定元素的可见性变化。
  • takeRecords():获取未处理的交叉状态变化记录并清空队列。
  • unobserve():停止观察 指定元素

MutationObserver

用于监听 DOM 树的变化,例如节点添加、删除、属性修改等。

js
const observer = new MutationObserver(mutations => {
  mutations.forEach(mutation => {
    console.log('DOM 发生变化', mutation)
  })
})

observer.observe(document.body, {
  childList: true,
  attributes: true,
  subtree: true,
})

实例方法:

  • disconnect():停止监听 DOM 变动。
  • observe():开始监听指定目标的 DOM 变动。
  • takeRecords():获取尚未处理的变动记录并清空队列。

ResizeObserver

用于监听元素尺寸的变化,常用于响应式布局或动态调整 UI。

js
const observer = new ResizeObserver(entries => {
  entries.forEach(entry => {
    console.log('元素尺寸变化', entry.contentRect)
  })
})

observer.observe(document.querySelector('.resizable-element'))

PerformanceObserver

用于监听性能指标,例如长任务、资源加载时间等。

js
const observer = new PerformanceObserver(list => {
  list.getEntries().forEach(entry => {
    console.log('性能指标', entry)
  })
})

observer.observe({ entryTypes: ['longtask', 'resource'] })

Custom Observer(自定义观察者)

如果需要监听自定义对象的变化,可以手动实现一个简单的观察者模式。

js
class Subject {
  constructor() {
    this.observers = []
  }

  subscribe(observer) {
    this.observers.push(observer)
  }

  unsubscribe(observer) {
    this.observers = this.observers.filter(obs => obs !== observer)
  }

  notify(data) {
    this.observers.forEach(observer => observer.update(data))
  }
}

class Observer {
  update(data) {
    console.log('收到更新', data)
  }
}

const subject = new Subject()
const observer = new Observer()
subject.subscribe(observer)

subject.notify('Hello, Observer!')

参考

基于 MIT 许可发布