提升网页交互体验:使用 useMultiIntersectionObserver 自定义 Hook 监听元素进出视图

在现代网页设计中,提供流畅且具有交互性的用户体验至关重要。监听元素进出视图的变化是实现这一目标的常见任务,但往往涉及繁琐的代码编写。为了简化这一过程,编写出了 useMultiIntersectionObserver 自定义 Hook,它能够轻松地监听元素的可见性变化。


介绍

useMultiIntersectionObserver 是一个自定义 Hook,用于监听一个或多个元素是否出现在视图中。它基于 Intersection Observer API,并封装了常用的功能,简化了代码编写过程。通过使用 useMultiIntersectionObserver,开发人员可以专注于实现各种交互效果,如图片懒加载和无限滚动,而无需过多关注底层的 Intersection Observer 实现细节。

使用方法

安装

首先,我们需要安装 st-multi-intersection-observer 包。在命令行中执行以下命令:

npm i st-multi-intersection-observer
引入与使用

引入 useMultiIntersectionObserver

import { useMultiIntersectionObserver } from 'st-multi-intersection-observer';
const multiIntersectionObserver = useMultiIntersectionObserver( dom/dom数组 , 回调事件 , IntersectionObserver配置参数(可不传) )

multiIntersectionObserver.unobserveElement() // unobserveElement 单个移除某个dom的监听事件
multiIntersectionObserver.unobserveAllElements() // unobserveAllElements 停止观察所有元素
multiIntersectionObserver.disconnectObserver() // unobserveAllElements disconnectObserver 关闭观察器

使用实例

图片懒加载

使用 useMultiIntersectionObserver,我们可以轻松实现图片懒加载的效果。

<template>
  <div>
    <img v-for="image in images" :key="image.src" class="lazy-image" :data-src="image.src" />
  </div>
</template>

<script>
import { ref, onMounted } from 'vue';
import { useMultiIntersectionObserver } from '@/hooks/useMultiIntersectionObserver';

export default {
  setup() {
    const images = ref([
      { src: 'path/to/image1.jpg' },
      { src: 'path/to/image2.jpg' },
      { src: 'path/to/image3.jpg' }
    ]);

    onMounted(() => {
      const { unobserveElement } = useMultiIntersectionObserver(document.querySelectorAll('.lazy-image'),  (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            entry.target.src = entry.target.dataset.src;
            unobserveElement(entry.target);
          }
        });
      },{});
    });

    return {
      images,
    };
  },
};
</script>

在上面的示例中,我们通过使用 useMultiIntersectionObserver 自定义 Hook 来监听带有 lazy-image 类名的图片元素的可见性变化。当图片元素进入视图时,将其 data-src 属性的值赋给 src 属性,实现图片的延迟加载效果。需要注意的是,确保在 img 元素上设置了 data-src 属性来存储真实的图片路径。

无限滚动

另一个常见的应用场景是实现无限滚动。通过监听滚动容器的底部元素是否进入视图,我们可以触发加载更多数据的逻辑,从而实现无限滚动的效果。

<template>
  <div ref="container" style="height: 500px; overflow-y: scroll;">
    <ul>
      <li v-for="item in items" :key="item">{{ item }}</li>
      <li ref="scrollEnd"></li>
    </ul>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue';
import { useMultiIntersectionObserver } from '@/hooks/useMultiIntersectionObserver';

export default {
  setup() {
    const items = ref(['Item 1', 'Item 2', 'Item 3']); // 初始数据

    const scrollEnd = ref(null);

    onMounted(() => {
      const { unobserveElement } = useMultiIntersectionObserver(scrollEnd.value, (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            // 触发加载更多数据的逻辑
            loadMoreData()
          }
        });
      }, {});
    });

    const loadMoreData = () => {
      // 模拟异步加载更多数据
      setTimeout(() => {
        const newItems = ['Item 4', 'Item 5', 'Item 6']; // 新加载的数据
        items.value = [...items.value, ...newItems];
      }, 1000);
    };

    return {
      items,
    };
  },
};
</script>

在上面的示例中,我们使用了 useMultiIntersectionObserver 自定义 Hook 来监听滚动容器底部元素 scrollEnd 的可见性变化。当底部元素进入视图时,会触发 loadMoreData 函数,该函数模拟异步加载更多数据,并将新数据追加到 items 数组中,实现了无限滚动的效果。请确保在滚动容器的 CSS 样式中设置了固定的高度和合适的滚动属性。

代码实现

让我们来逐步介绍 useMultiIntersectionObserver 的代码实现。

首先,定义了一个函数,命名为 useMultiIntersectionObserver,该函数接收三个参数:elements、options 和 callback。

    export function useMultiIntersectionObserver(elements, callback,options = {} ) {
      // ...
    }
  • elements:表示要监听的元素,可以是单个元素或元素数组。
  • options:表示 IntersectionObserver 的配置参数,可选。
  • callback:表示元素进出视图时的回调函数,可选。

接下来,我们需要进行参数验证。如果 elements 参数为空或为一个空数组,则抛出错误。

    if (!elements || (Array.isArray(elements) && elements.length === 0)) {
      throw new Error('参数 elements 不能为空');
    }

然后,我们需要判断 elements 是单个元素还是元素数组,并将其统一转为数组形式。

    const isSingleElement = !Array.isArray(elements);
    const targetElements = isSingleElement ? [elements] : elements;

接下来,我们创建一个 IntersectionObserver 实例对象,传入回调函数和配置参数。

    const observer = new IntersectionObserver((entries, observer) => {
      callback && callback(entries, observer);
    }, options);

在创建实例后,我们需要开始监听 DOM 变化。遍历 targetElements 数组,并对每个元素调用 observe 方法。

    targetElements.forEach((element) => {
      observer.observe(element);
    });

在这里,我们已经完成了 useMultiIntersectionObserver 的主要实现部分。

停止观察某个元素

如果我们想停止观察特定的元素,可以使用 unobserveElement 方法。该方法接收一个参数 element,表示要停止观察的 DOM 元素。

    const unobserveElement = (element) => {
      if (element) {
        observer.unobserve(element);
      }
    };
停止观察所有元素

如果我们想停止观察所有元素,可以使用 unobserveAllElements 方法。

    const unobserveAllElements = () => {
      targetElements.forEach((element) => {
        observer.unobserve(element);
      });
    };
关闭观察器

如果我们想完全关闭观察器,可以使用 disconnectObserver 方法。

    const disconnectObserver = () => {
      observer.disconnect();
    };

最后,我们需要返回这些方法作为结果。

return {
  unobserveElement,
  unobserveAllElements,
  disconnectObserver,
};
完整代码

下面是 useMultiIntersectionObserver 的完整代码实现:

export function useMultiIntersectionObserver(elements, callback,options = {} ) {
  if (!elements || (Array.isArray(elements) && elements.length === 0)) {
    throw new Error('参数 elements 不能为空');
  }

  const isSingleElement = !Array.isArray(elements);
  const targetElements = isSingleElement ? [elements] : elements;

  const observer = new IntersectionObserver((entries, observer) => {
    callback && callback(entries, observer);
  }, options);

  targetElements.forEach((element) => {
    observer.observe(element);
  });

  const unobserveElement = (element) => {
    if (element) {
      observer.unobserve(element);
    }
  };

  const unobserveAllElements = () => {
    targetElements.forEach((element) => {
      observer.unobserve(element);
    });
  };

  const disconnectObserver = () => {
    observer.disconnect();
  };

  return {
    unobserveElement,
    unobserveAllElements,
    disconnectObserver,
  };
}

特点

  • 简化代码:useMultiIntersectionObserver 封装了底层的 Intersection Observer 实现细节,使代码更加简洁和易于理解。
  • 灵活可配置:通过 options 参数,您可以自定义 Intersection Observer 的配置,以满足不同的需求。
  • 适用于多种场景:useMultiIntersectionObserver 可以应用于图片懒加载、无限滚动等多种场景,提供了更好的交互体验。

结语

通过使用 useMultiIntersectionObserver 自定义 Hook,我们可以轻松地监听元素的可见性变化,从而实现各种交互效果。无论是图片懒加载还是无限滚动,它都为我们提供了简单且灵活的解决方案。希望本文对您理解和使用 useMultiIntersectionObserver 有所帮助,并为提升网页交互体验提供了新的思路。

让我们一起解放双手,优化前端开发!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值