结合 Vue 自定义指令和 Intersection Observer API 实现元素视口可见性检测
1. 实现元素可见性检测
知识铺垫
Intersection Observer API 简介
- 什么是 Intersection Observer API?
- 它的主要用途:检测元素是否进入视口或与某个父元素相交。
- 区别于以往的判断元素距离顶部距离和滚动距离,使用Intersection Observer性能更好
Vue 自定义指令基础
- Vue 自定义指令的基本语法。
- 生命周期钩子:
mounted
、updated
、unmounted
等。 - 如何通过
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. 补充说明
可用使用的场景
- 懒加载图片或组件。
- 无限滚动列表。
- 动画触发条件。
- 数据埋点(如曝光统计)。
优化与扩展
- 动态调整
threshold
和rootMargin
。 - 处理多个元素的可见性检测。
- 结合 Vue 的响应式系统实现更复杂的功能。
注意事项
- 兼容性问题:
IntersectionObserver
的浏览器支持情况。 - 性能优化:避免过度使用观察器。
- 清理资源:确保在组件销毁时断开观察器。