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>
相关推荐
十九画生18 小时前
parentID ``` JavaScript 是区分大小写的,所以这两个不是同一个字段。 第二,`parent` 没有声明。 应该先写: `
javascript
秃头网友小李18 小时前
前端难点:keep-alive 缓存什么?RouterView 的 key 为什么要带 scopeId?
前端·vue.js
鱼人18 小时前
CSS 变量:一个变量救你一百次复制粘贴
前端
长大198819 小时前
CSS 到底是什么?和 HTML 的区别一次讲清楚
前端
禅思院19 小时前
路由性能优化终极指南:从懒加载漏洞到边缘渲染的架构跃迁
前端·架构·前端框架
怕浪猫19 小时前
Electron 开发实战(十六):总结与展望|生态现状、框架对比、行业趋势与学习指南
前端·javascript·electron
文心快码BaiduComate19 小时前
Comate 搭载GLM-5.2:百万上下文,稳定支撑长程任务
前端·程序员·开源
星栈19 小时前
Dioxus 的 `rsx!` 语法:如果你会 React,上手确实特别快
前端·前端框架
Momo__19 小时前
TypeScript NoInfer<T>——精准控制泛型推断的工具类型
前端·typescript
lichenyang45319 小时前
从 Web 容器开始,理解 ASCF 元服务开发
前端