me

Observer


Observer

Important

网页开发中经常会和用户交互而使用一些监听事件(例如 onclick、onchange 等)。如果对于一些用户不直接触发的元素(例如渐变等),那就需要使用 Observer 去监听

IntersectionObserver

IntersectionObserver(交叉观察者)用于观察一个元素是否在视窗可见。构造函数创建并返回一个新的IntersectionObserver对象

如果未指定或为空字符串,则缺省的值为属性的默认值

一般用于无限滚动图片懒加载埋点控制动画/视频执行

实例方法

创建观察者

let options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  //阈值为 1.0 表示当 100% 的目标在选项指定的元素中可见时,将调用回调
  //每个阈值是观测目标的交集区域与边界框区域的比率
  threshold: 1.0
}

let observer = new IntersectionObserver(callback, options?);

option 字段

监听观察的目标对象

开启对目标对象的监听,如果没有

const target = document.querySelector('.target')
observer.observe(target)

回调函数

callback 是添加监听后,当监听目标发生滚动变化时触发的回调函数。

属性说明
boundingClientRect返回包含目标元素的边界信息,返回结果与 getBoundingClientRect() 相同
intersectionRatio返回目标元素出现在可视区的比例
intersectionRect用来描述 root 和目标元素的相交区域
isIntersecting返回布尔值,下列两种操作均触发回调:1.如果目标元素出现在 root 可视区,返回 true。2. 如果从 root 可视区消失,返回 false
rootBounds用来描述交叉区域观察者中的根。
target目标元素:与根出现相交区域改变的元素
time返回一个记录从 IntersectionObserver 的时间原点到交叉被触发的时间的时间戳

图片懒加载

<body>
  <img width="200px" height="200px" src="logo.png" data-src="0.jpg" />
  <img width="200px" height="200px" src="logo.png" data-src="1.jpg" />
  <img width="200px" height="200px" src="logo.png" data-src="2.jpg" />
</body>
<script>
  const img = document.getElementsByTagName('img')
  let observe = new IntersectionObserver(
    (entries, observe) => {
      entries.forEach((item) => {
        if (item.isIntersecting) {
          item.target.src = item.target.dataset.src
          observe.unobserve(item.target)
        }
      })
    },
    { rootMargin: '0px 600px 0px -600px' }
  )
  // observe 遍历监听所有 img 节点
  Array.from(img).forEach((img) => observe.observe(img))
</script>

HTMLCollectionOfNodeListOf的区别

理解可视区

MutationObserver

Mutation 实例方法

Mutation 创建观察者和监听目标对象

const MutationObserver = new MutationObserver(callback)
MutationObserver.observe(dom, options)

mutation 回调函数

同样是接收两个参数

属性描述
target被修改影响的目标 dom 节点
type变化的类型,也就是 MutationObserverInit 对象中的三种 attributescharacterDatachildList,并且返回该类型
attributeName针对 attributes 类型的变化时,返回被修改属性的名字(或者 null)
attributeNamespace针对命名空间的attributes类型的变化。返回被修改属性的命名空间,或者 null
oldValue如果在 MutationObserverInit对象中启用(attributeOldValuecharacterDataOldValue 为 true)。则 attributescharacterData 的变化事件会返回变化之值或数据。childList类型的变化始终将这个属性设置为 null
addedNodes针对 childList 的变化,返回包含变化中添加节点的 NodeList,没有节点被添加,返回空 NodeList 数组
previousSibling对于 childList 变化。返回被添加或移除的节点之前的兄弟节点,或者 null
nextSibling对于 childList 变化,返回被添加或移除的节点之后的兄弟节点。或者 null
removedNodes对于 childList 变化,返回被移除的节点 (没有则为 null)

MutationObserver 的引用

MutationRecord 的引用

ResizeObserver

Resize 实例方法

创建 Resize 实例

const ResizeObserver = new ResizeObserver(callback)
resizeObserver.observe(target, options?);
resizeObserver.observe(target, { box: 'content-box' })

Resize 回调函数

PerformanceObserver

PerformanceObserver 用于监测性能度量事件,在浏览器的性能时间轴记录下一个新的 performance entries 的时候将会被通知

实例方法和 MutationsObserver 一样,但是 observe() 只接受 options

创建 Performance 实例

const PerformanceObserver = new PerformanceObserver(callback)
PerformanceObserver.observe({ entryTypes: ['measure'] })
属性别名类型描述
frame, navigationPerformanceFrameTiming, PerformanceNavigationTimingURL文件的地址
resourcePerformanceResourceTimingURL文件请求资源解析的 URL。只有在资源加载完毕后才会创建
markPerformanceMarkDOMString通过调用创建标记使用的名称。会在资源获取开始时创建 performance.mark(name)
measurePerformanceMeasureDOMString通过调用创建度量时使用的名称。会在对资源操作时创建 performance.measure(name)
paintPerformancePaintTimingDOMString渲染时间点的信息接口。找出那些花费太多时间去绘制的区域

Performance 回调函数

回调函数只接受一个参数,该参数 PerformanceObserverEntryList 对象。该对象有三个接口

PerformanceEntry 对象

<body>
  <button onclick="measureClick()">Measure</button>
  <img
    src="http://zyjcould.ltd/blog/%E6%B5%8F%E8%A7%88%E5%99%A8%E8%A7%86%E5%8F%A3.png"
  />
  <script>
    const performanceObserver = new PerformanceObserver((list) => {
      list.getEntries().forEach((entry) => {
        console.log(entry.entryType)
        console.log(entry.startTime)
        console.log(entry.name)
        console.log(entry.duration)
        console.log(entry.toJSON())
      })
    })
    performanceObserver.observe({ entryTypes: ['resource', 'mark', 'measure'] })

    performance.mark('registered-observer')

    function measureClick() {
      performance.measure('button clicked')
    }
  </script>
</body>

ReportingObserver(实验)

ReportingObserver() 构造函数会创建一个新的 ReportingObserver 对象实例,该实例可用于收集和获取 reports

ReportingObserver 实例方法和 MutationObserver 的实例方法一样。但是 observer() 不需要任何参数

创建 Reporting 实例

let options = {
  types: ['deprecation'],
  buffered: true
}
const reportingObserver=new ReportingObserver(callback, options?)

Reporting 回调函数

提供两个参数,第一个参数是一个 reports 数组对象。同样也可以通过 takeRecords() 实例方法获取这些数组