npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

st-multi-intersection-observer

v1.1.1

Published

观察元素是否出现在可视窗口中,简化复杂操作,易化监听操作;

Downloads

14

Readme

在现代网页设计中,提供流畅且具有交互性的用户体验至关重要。监听元素进出视图的变化是实现这一目标的常见任务,但往往涉及繁琐的代码编写。为了简化这一过程,编写出了 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('.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, options = {}, callback) {
      // ...
    }
  • 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, options = {}, callback) {
  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 有所帮助,并为提升网页交互体验提供了新的思路。

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