当前位置: 首页 > news >正文

Vue3中到达可视区域后执行

项目场景:

提示:这里简述项目相关背景:

在项目中有时候需要显示一些动态效果,但是如果页面过长刷新页面的时候有些效果在没看到的时候就会执行,那么能滚动到那个区域的时候哪些动态效果就在没看到的时候就已经执行过了,那怎么才能让后滚动到可视区域的时候才执行呢?

在Vue 3中,要判断一个元素是否到达可视区域,你可以使用几种不同的方法。最常见和直接的方法是利用Intersection Observer API

Intersection Observer是一个非常强大的API,可以自动“观察”目标元素是否进入其祖先元素或顶级文档视口的可见区域。

到达可视区域的时候就会执行


分析:

提示:这里填写问题的分析:

 首先需要时vue3项目,另外,要在onMounted钩子函数中作操作

基本操作如下

1:使用Intersection Observer

<template><div ref="observerElement" class="observed-element">我是需要观察的元素</div>
</template><script setup>
import { ref, onMounted } from 'vue';const observerElement = ref(null);onMounted(() => {const options = {root: null, // 使用视口作为参照点rootMargin: '0px',threshold: 0.1 // 元素10%在视口内时触发回调};const callback = (entries, observer) => {entries.forEach(entry => {if (entry.isIntersecting) {console.log('元素进入了视口!');} else {console.log('元素离开了视口。');}});};const observer = new IntersectionObserver(callback, options);if (observerElement.value) {observer.observe(observerElement.value);}
});
</script>

 2:计算元素位置与视口的关系

如果你不希望使用Intersection Observer API,你可以通过计算元素的位置来判断它是否进入视口。这通常涉及到获取元素的位置和视口的高度。

<template><div ref="element" class="observed-element">我是需要观察的元素</div>
</template><script setup>
import { ref, onMounted } from 'vue';const element = ref(null);onMounted(() => {const checkVisibility = () => {if (!element.value) return;const rect = element.value.getBoundingClientRect();const isVisible = (rect.top >= 0 &&rect.left >= 0 &&rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&rect.right <= (window.innerWidth || document.documentElement.clientWidth));if (isVisible) {console.log('元素进入了视口!');} else {console.log('元素离开了视口。');}};checkVisibility(); // 初始检查一次// 添加滚动事件监听器以持续检查window.addEventListener('scroll', checkVisibility); // 添加窗口大小改变事件监听器以持续检查window.addEventListener('resize', checkVisibility); 
});
</script>

方案实例:

提示:这里填写该问题的具体解决方案:

在组件中使用这个方法直接在子组件中使用不需要再父组件中操作

如下:

父组件:

<!-- 使用子组件 --><bannerGreen:bannerInfo="bannerInfo"/>//引入子组件
import bannerGreen from '@/view/Home/components/bannerGreen.vue';

子组件

<template><div ref="observerElement" class="observed-element flexEv bannerBg padTB100 padLR65 colorW"><div class="flex" v-for="item in props.bannerInfo"><div class="borderR paddingR20 flexC"><i :class="item.icon" class="iconfont fontS40 fontW4 colorW hoverS"></i></div><div class="paddingL20"><div ref="numRef" class="fontS26 fontW6 marginB10 number inLb":data-target="item.textTop"></div> <div class="fontS26 fontW6 inLb">+</div><div class="fontS18 fontW5">{{item.textBottom}}</div></div></div></div>
</template><script lang="ts" setup>
import {reactive,toRefs,ref,Ref,PropType,onMounted,onBeforeUnmount,
} from "vue"
const props=defineProps({// bannerInfo:{type:Array},
})
// 自动将数值加到会后那个值的方法
const changeNum=()=>{// 获取元素const numbers = document.querySelectorAll('.number')console.log("",numbers)// 获取所有的dom,querySelectorAll为为数组numbers.forEach(item => {item.textContent = "0";const upDateNumber = () => {// 获取每个类名为number的data-target,即获取最大值 const target = Number(item.getAttribute('data-target'))// 获取当前div的数值const d = Number(item.textContent)// 设置数据增加的值,可以通过target除的数值确定怎么加数值的快慢const increment = target / 100// 当数字小于最大值时,执行下面的操作if (d < target) {// 向上取整item.textContent = `${Math.ceil(d + increment)}`// 1ms重新调用,不然它会在第一次运行完就结束setTimeout(upDateNumber, 10)} else {item.textContent = target+"";//textContent的值是 字符串 所以加个空字符}}upDateNumber()})
}
onMounted(()=>{console.log()})
// ================================到达可视区域的方法
const observerElement = ref(null);
onMounted(() => {const options = {root: null, // 使用视口作为参照点rootMargin: '0px',threshold: 0.1 // 元素10%在视口内时触发回调};const callback = (entries:any, observer:any) => {entries.forEach((entry:any) => {if (entry.isIntersecting) {console.log('元素进入了视口!');//到达可视区域 执行 数字自增的方法changeNum()} else {console.log('元素离开了视口。');}});};const observer = new IntersectionObserver(callback, options);if (observerElement.value) {observer.observe(observerElement.value);}
});
onBeforeUnmount(()=>{console.log()
})
const emit =defineEmits([""
])</script><style lang="less" scoped>
.bannerBg{background-color:#1d7b51 ;
}
.borderR{border-right: 1px solid #ffffff;
}
</style>

http://www.xdnf.cn/news/229825.html

相关文章:

  • mac电脑pytest生成测试报告
  • Java高阶程序员学习计划(详细到天,需有一定Java基础)
  • Webug4.0通关笔记06- 第8关CSV注入
  • golang接口和具体实现之间的类型转换
  • 分布式架构:Dubbo 协议如何做接口测试
  • 定时任务xxl-job国产化改造,适配磐维数据库(PostgreSQL)
  • OpenHarmony - 小型系统内核(LiteOS-A)(完),内核编码规范
  • Arduino项目实战与编程技术详解
  • Python爬虫学习路径与实战指南 04
  • (Go Gin)Gin学习笔记(三)数据解析和绑定:结构体分析,包括JSON解析、form解析、URL解析,区分绑定的Bind方法
  • 【思考】欧洲大停电分析
  • 0.安装两个版本的JDK8和JDK17并配置环境变量
  • 用Ai学习wxWidgets笔记——自制wxWidgets开发参考手册(主体)
  • MVC与MVP设计模式
  • 数据接收全流程图(物理网卡 → 应用层)
  • 第16篇:Linux设备驱动程序入门<三>
  • 自定义项目中导入文件import顺序
  • 前端 - 冷加载和热加载有什么区别?
  • DeepSeek谈《凤凰项目 一个IT运维的传奇故事》
  • 设计模式(构建者模式)
  • 【计算机视觉】图像分割:Segment Anything (SAM):通用图像分割的范式革命
  • 芯知识|WT2000T录音芯片应用会议录音设备解析:高保真降噪与低功耗兼得
  • 安卓基础(Looper和Handler)
  • React 第三十六节 Router 中 useParams 的具体使用及详细介绍
  • Docker搜索镜像报错
  • OpenCV 图形API(76)图像与通道拼接函数-----对输入图像进行归一化操作函数normalize()
  • OpenCV的grabCut算法分割图像
  • 六、UI自动化测试06--PO设计模式
  • QT—布局管理器之QStackedLayout篇
  • UE5 项目迁移 注意事项记录