IntersectionObserver分享

一、IntersectionObserver API介绍:

1.概念

Intersection Observer API 提供 种异步观察 标元素与祖先元素或顶级 档viewport的交集中的变化的 法。

## 1.用法

1. 新建observer实

const observer = new IntersectionObserver(callback, options);

callback:回调函数, 标元素的可 性发 变化时触发,参数为 IntersectionObserverEntry 对象的集合, 包含这个observer观察的所有 标元素中可 性变化的元素,每个元素对应 个 IntersectionObserverEntry。

IntersectionObserverEntry:描述 标元素与其根元素容 在某 特定过渡时刻的交叉状态。对象的属 性有:

  • boundingClientRect: 同getBoundingClientRect()
  • intersectionRatio: 标元素可视区内的部分与全部的 值
  • intersectionRect: 标元素可视区内的部分
  • isIntersecting: 是否进 可视区
  • rootBounds: 根元素
  • target: 标元素
  • time: 从开始到触发回调的时间

options: observer 的配置选项:

  • root: 于观察的根元素,需要是 个dom元素, 传或传null的时候默认为浏览 视
  • rootMargin: 根元素的margin,margin区域算 可视区,(正margin增 ,负margin减 ),写法同css
    -threshold: 进 可视区的阈值,进 可视区的 达到阈值时才触发回调,默认为0,可以传 个数

字或数组,传 数组时,每达到 个阈值触发 次 - isIntersecting: 是否进 可视区

2. 观察 标元素

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

同 个observer可以观察多个元素,但 个元素只能同时被 个 observer 观察,后添加的会替换之前的 需 要观察时可以取消观察 标或取消 observer

observer.unobserve(target) // 取消观察target observer.disconnect() // 停  作

二、注意点

  • rootMargin 为0时要加上px
  • threshold为0且缓慢滚动时,intersectionRatio有时会有问题
  • 根元素必须是 标元素的祖先元素

三、实例

1.懒加载

  <template>
   <div class="root">
     <ul>
       <li v-show="true" ref="li" v-for="(item, index) in list" :key="index">
         {{index}}
       </li>
</ul> </div>
</template>
 const options = {
   root: null,
   rootMargin: '0px 0px -200px 0px',
   threshold: 0
 }
 const observer = new IntersectionObserver(
   entries => {
     entries.forEach(entry => {
       if (entry.isIntersecting) {
         entry.target.innerText = `${entry.target.innerText}----loaded`
         observer.unobserve(entry.target)
} })
},
options )
 const ul = this.$refs.li
 // observer.observe(ul[0])
 ul.forEach(li => {
   observer.observe(li)
 })

2. 限滚动(滚动加载)

 <template>
  <div class="root">
    <ul>
      <li v-show="true" ref="li" v-for="(item, index) in list" :key="index">
        {{index}}
      </li>
</ul>
    <div class="trailer" ref="trailer" v-show="showTrailer"></div>
  </div>
</template>
const trailerObserver = new IntersectionObserver(entries => {
  if (entries[0].isIntersecting) {
    this.showTrailer = false
    setTimeout(() => {
      this.list.push(this.list.length)
      this.showTrailer = true
    }, 500)
} })
trailerObserver.observe(this.$refs.trailer)

tips:

  • 标元素height为0并没有影响
  • 切换 display: none 会触发回调函数

猜你喜欢

转载自blog.csdn.net/qq_32885597/article/details/89680817