JavaScript API: IntersectionObserver

简介

IntersectionObserver 是一个 JavaScript API,用于监测一个元素与其父元素或视窗的交叉状态。它可以用来判断一个元素是否可见或者在视窗中的位置是否发生变化。

使用 IntersectionObserver,你可以注册一个回调函数,当被观察的元素进入或离开视窗,或者与其父元素发生交叉时,该回调函数将被触发。这个 API 提供了一种高效的方法来监测元素的可见性,尤其在处理滚动事件时非常有用。

通过 IntersectionObserver,你可以实现一些常见的功能,例如延迟加载(当元素进入视窗时再加载内容)、无限滚动(滚动到底部时加载更多内容)以及元素的懒加载(当元素进入视窗时再加载真实内容,而不是占位符)等。它能够帮助你提高页面性能,减少不必要的资源加载,以及改善用户体验。

总结来说,IntersectionObserver 是一个用于监测元素可见性和位置变化的 API,可以实现一些常见的交互效果和性能优化。

具体内容见官方文档:https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver

下面说两个简单的应用案例

案例一:滚动动画

JavaScript API: IntersectionObserver_第1张图片






案例二:无限滚动(滚动到底部时加载更多内容)

这个应用应该更广泛一点,原来判断是否滚动到底的话一般是采用下面这种方案


现在的话可以通过IntersectionObserver 来实现,基本思路是:

  • 创建一个 IntersectionObserver 实例,指定观测的根元素(滚动容器)和阈值(thresholds)。
  • 将最后一个加载元素作为观测目标,调用 IntersectionObserverobserve 方法开始观测。
  • IntersectionObserver 的回调函数中,当最后一个加载元素与容器底部交叉时,触发加载更多的操作。
  • 加载更多的操作可以是异步请求数据,更新页面内容等。
  • 在加载完成后,更新最后一个加载元素的位置,继续观测。

JavaScript API: IntersectionObserver_第2张图片
JavaScript API: IntersectionObserver_第3张图片






优点

<template>
  <div v-loading="loading">
    <div id="abc">
      <div v-for="item in list" :key="item" class="observer-item">
        content-{{ item }}
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from "vue";

const list = ref([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
const loading = ref(false);
const lastElement = ref();

onMounted(() => {
  // 使用IntersectionObserver 来检测子元素与父元素的交叉状态
  const observer = new IntersectionObserver(callback);
  // 观察最后一个元素
  lastElement.value = document.querySelector(".observer-item:last-child");
  // 观察元素
  observer.observe(lastElement.value);

  function callback(entries, instance) {
    entries.forEach((entry) => {
      // 判断元素是否出现在父元素中
      if (entry.isIntersecting) {
        const target = entry.target;
        console.log("滚动到底了:", target);
        // 加载新数据
        // 取消上一个元素的观察
        instance.unobserve(lastElement.value);
        if (list.value.length < 15) {
          loading.value = true;
          list.value.push(...[11, 12, 13, 14, 15]);
          setTimeout(() => {
            // 更新新的观察对象
            lastElement.value = document.querySelector(
              ".observer-item:last-child"
            );
            observer.observe(lastElement.value);
            loading.value = false;
          }, 1000);
        }
      }
    });
  }
});
</script>

<style scoped>
#abc {
  width: 400px;
  height: 300px;
  border: 1px solid red;
  overflow-y: scroll;
  margin-left: 500px;
}
.observer-item {
  width: 100%;
  height: 100px;
  line-height: 100px;
  margin-bottom: 20px;
}
.observer-item:nth-child(odd) {
  background-color: pink;
}
.observer-item:nth-child(even) {
  background-color: skyblue;
}
</style>

兼容性

JavaScript API: IntersectionObserver_第4张图片

你可能感兴趣的:(学习,JavaScript,javascript)