背景

我的书签项目预览页想添加滚动时视窗内的元素显示,视窗外的元素隐藏的过渡效果,提高页面的吸引力

实现

通过IntersectionObserverj监听每一个模块是否在视窗内,结合Animate.CSS动态的添加和移除class类名

前提:main.js入口文件引入animate.css动画库

useHidden.ts

// // 图标懒加载
import { onBeforeUnmount } from 'vue';

function useHidden() {
  let container: HTMLElement;
  let itemList: HTMLElement[];
  let Observer: IntersectionObserver;

  function lazyLoad() {
    const options = {
      rootMargin: '0px',
      threshold: 0.1,
    };
    Observer = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        // 通过该属性判断元素是否出现在视口内
        const item = entry.target;
        if (entry.isIntersecting) {
          // item.classList.remove('hidden');
          item.classList.add('animate__zoomIn');
        } else {
          // item.classList.add('hidden');
          item.classList.remove('animate__zoomIn');
        }
      });
    }, options);
    itemList.forEach((item) => {
      Observer.observe(item);
    });
  }

  function init(originalContainer: HTMLElement) {
    container = originalContainer;
    itemList = Array.from(container.children) as HTMLElement[];
    lazyLoad();
  }

  onBeforeUnmount(() => {
    itemList.forEach((item) => {
      Observer.unobserve(item);
    });
  });

  return { init };
}

export default useHidden;

使用

  import useHidden from '@/hooks/useHidden';

  const { init } = useHidden();

  // 在需要用的方法中使用
  // 监听元素显示隐藏
  init(instance?.proxy?.$refs.waterfallContainerRef as HTMLElement);