vue3 滚动条滑动到元素位置时,元素加载

水个文

效果

要实现的思路就是,使用IntersectionObserver 检测元素是否在视口中显示,然后在通过css来进行动画载入。

1.监控元素是否视口中显示

javascript 复制代码
      const observer = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            acc.value = true
          }
        });
      });

      //监控元素
      observer.observe(slideInAnimation.value);

其中 if里就是当元素显示在视口中要执行的逻辑

然后在调用,在里面要传入要监控元素的元素对象,这里要在onmounted里调用,注意异步

javascript 复制代码
    onMounted(() => {
      //监控元素
      observer.observe(slideInAnimation.value);
    });

2.设置css

css 复制代码
.box {
  overflow: hidden;
  height: 4000px;
  /* 为了演示效果,设置一个高度 */
  display: flex;
  justify-content: center;
  align-items: center;
}

.slide-in-animation,
.onslide-in-animation {
  width: 400px;
  height: 200px;
}  //定义一个基础的数据,

.slide-in-animation {  //这个是要载入时,将css替换即可
  background-color: #f00;
  position: relative;
  animation: slide-in 4s forwards; //持续时间
}

@keyframes slide-in { //定义加载方式
  0% {
    visibility: hidden; //当百分0时元素不显示,从最右边加载,
    left: 100%;
  }

  100% { 
    left: 0%;  //百分百时加载到最左边
  }
}

大概是这个个逻辑,然后通过三目运算来控制class的值

html 复制代码
  <div class="box">
    <div :class="acc ? 'slide-in-animation' : 'onslide-in-animation'" ref="slideInAnimation">
      <img src="https://www.gm.com/assets/%E5%8D%81%E5%9B%9B%E6%9C%9F-CKW22HE9.png" alt=""
        style="width:400px;height:200px;">
    </div>

  </div>

acc最开始是false,不显示,而当元素在视口里时,将slide-in-animation类名加入,执行动画,然后实现滑动到元素位置时元素滑动载入,这里我只是做了一个示例,通过 @keyframes 可以实现更复杂的效果

源码

html 复制代码
<template>
  <div class="box">
    <div :class="acc ? 'slide-in-animation' : 'onslide-in-animation'" ref="slideInAnimation">
      <img src="https://www.gm.com/assets/%E5%8D%81%E5%9B%9B%E6%9C%9F-CKW22HE9.png" alt=""
        style="width:400px;height:200px;">
    </div>

  </div>
</template>

<script>
import { defineComponent, ref, onMounted } from 'vue';

export default defineComponent({
  setup() {
    const slideInAnimation = ref(null);
    const observer = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            acc.value = true
          }
        });
      });
    onMounted(() => {
      //监控元素
      observer.observe(slideInAnimation.value);
    });
    const acc = ref(false)

    return {
      slideInAnimation, acc
    };
  }
});
</script>

<style scoped>
.box {
  overflow: hidden;
  height: 4000px;
  /* 为了演示效果,设置一个高度 */
  display: flex;
  justify-content: center;
  align-items: center;
}

.slide-in-animation,
.onslide-in-animation {
  width: 400px;
  height: 200px;
  
}

.slide-in-animation {
  background-color: #f00;
  position: relative;
  animation: slide-in 4s forwards;
}

@keyframes slide-in {
  0% {
    visibility: hidden;
    left: 100%;
  }

  100% {
    left: 0%;
  }
}
</style>
相关推荐
Larcher3 小时前
React Router 不只是页面跳转:从 SPA 路由到权限守卫的完整实践
javascript·后端
Larcher3 小时前
大模型为什么每次回答都不一样?一文搞懂 Temperature、Top K 与 Top P
javascript·后端
用户938515635076 小时前
从零在浏览器里跑 DeepSeek-R1:WebGPU + Transformer.js 全链路实战
前端·设计模式·typescript
CodeSheep6 小时前
稚晖君公司人事大变动,来了!
前端·后端·程序员
鱼樱前端6 小时前
用 AI 做内容变收入
前端·人工智能·ai编程
eric-sjq7 小时前
10 分钟实战:用 0.6B 本地模型生成中文网页(WanlyFrontend + 编译器全流程)
javascript·机器学习·自然语言处理·html
浮生望7 小时前
React + TypeScript 组件设计进阶:从类型约束到无状态组件的三次进化
前端
To_OC7 小时前
LC 438 找到所有字母异位词:暴力超时后,我靠滑动窗口一招搞定
javascript·算法·leetcode
90后的晨仔7 小时前
Mac 开发 uni-app 终极方案:让安卓模拟器彻底脱离 Android Studio 独立运行
前端·vue.js
90后的晨仔7 小时前
别再搞混了!uni-app 中 node_modules 和 uni_modules 到底是什么关系?
前端