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>
相关推荐
jump_jump9 分钟前
SaaS 时代已死,SaaS 时代已来
前端·后端·架构
Yanni4Night29 分钟前
Parcel 作者:如何用静态Hermes把JavaScript编译成C语言
前端·javascript·rust
hellokatewj31 分钟前
前端 Promise 全解:从原理到面试
前端
天意pt39 分钟前
Blog-SSR 系统操作手册(v1.0.0)
前端·vue.js·redis·mysql·docker·node.js·express
遗憾随她而去.41 分钟前
Webpack5 高级篇(一)
前端
遇见~未来1 小时前
JavaScript构造函数与Class终极指南
开发语言·javascript·原型模式
清风ai明月1 小时前
在vue3中Promise是什么
vue.js
疯狂踩坑人1 小时前
【React 19 尝鲜】第一篇:use和useActionState
前端·react.js
毕设源码-邱学长1 小时前
【开题答辩全过程】以 基于VUE的打车系统的设计与实现为例,包含答辩的问题和答案
前端·javascript·vue.js
用户39051332192881 小时前
JS判断空值只知道“||”?不如来试试这个操作符
前端·javascript