《元素视口可见性检测 》Vue自定义指令 封装

结合 Vue 自定义指令和 Intersection Observer API 实现元素视口可见性检测

1. 实现元素可见性检测

知识铺垫

Intersection Observer API 简介

  • 什么是 Intersection Observer API?
    • 它的主要用途:检测元素是否进入视口或与某个父元素相交。
  • 区别于以往的判断元素距离顶部距离和滚动距离,使用Intersection Observer性能更好

Vue 自定义指令基础

  • Vue 自定义指令的基本语法。
  • 生命周期钩子:mountedupdatedunmounted 等。
  • 如何通过 binding 传递参数和值。
  • 代码解析:
    • mounted 钩子中创建 IntersectionObserver 实例。
    • 使用 threshold 控制触发条件。
    • 通过 binding.value 传递回调函数。
    • unmounted 钩子中清理观察器。

2. 开袋即食·代码:

以下封装好的代码可以直接复制,粘贴到项目的任意js文件中

比如我放在 src/utils/diy_directive_visible.js

javascript 复制代码
export default {
  mounted(el, binding) {
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          binding.value(entry.isIntersecting);
        });
      },
      {
        threshold: 0.5, // 50%可见时触发
        rootMargin: "0px",
      },
    );
    observer.observe(el);
    el._observer = observer;
  },
  unmounted(el) {
    el._observer?.disconnect();
  },
};

在你的main.js中,进行导入和全局注册

javascript 复制代码
import visible from "./utils/diy_directive_visible.js"  // 导入自己配置的指令
....省略部分内容
const app = createApp(App)
app.directive("visible", visible) //  注册自己配置的指令
....省略部分内容
app.mount("#app")

组件中的使用示例

html 复制代码
<template>
  <div v-visible="handleVisibility">滚动到这里看看!</div>
</template>

<script>
export default {
  methods: {
    handleVisibility(isVisible) {
      if (isVisible) {
        console.log('元素可见!');
      } else {
        console.log('元素不可见!');
      }
    },
  },
};
</script>

3. 补充说明

可用使用的场景

  • 懒加载图片或组件。
  • 无限滚动列表。
  • 动画触发条件。
  • 数据埋点(如曝光统计)。

优化与扩展

  • 动态调整 thresholdrootMargin
  • 处理多个元素的可见性检测。
  • 结合 Vue 的响应式系统实现更复杂的功能。

注意事项

  • 兼容性问题:IntersectionObserver 的浏览器支持情况。
  • 性能优化:避免过度使用观察器。
  • 清理资源:确保在组件销毁时断开观察器。
相关推荐
江城开朗的豌豆2 分钟前
useLayoutEffect:你以为它和useEffect是"亲兄弟"?其实差别大了!
前端·javascript·react.js
江城开朗的豌豆7 分钟前
聊聊useEffect:谁说副作用不能“优雅”?
前端·javascript·react.js
!执行9 分钟前
开发electron时候Chromium 报 Not allowed to load local resource → 空白页。
前端·javascript·electron
top_designer13 分钟前
告别“复制粘贴”式换肤:我用Adobe XD组件变体与CC库,构建多品牌设计系统架构
前端·ui·adobe·系统架构·ux·设计师·adobe xd
赛博切图仔27 分钟前
面试手写 Promise:链式 + 静态方法全实现
前端·javascript·面试
掘金安东尼33 分钟前
互联网不再由 URL 为核心入口
前端·人工智能·github
Moment36 分钟前
面试官:用户访问到一个不存在的路由,如何重定向到404 Not Found的页面 ❓❓❓
前端·javascript·面试
前端小巷子38 分钟前
深入 Vue3 computed
前端·vue.js·面试
未来的旋律~1 小时前
Web程序设计
前端
全宝1 小时前
实现一个有意思的眼球跟随卡片
前端·javascript·css