当前位置:首页 » 《随便一记》 » 正文

前端加载动画效果的实现

13 人参与  2024年11月04日 14:40  分类 : 《随便一记》  评论

点击全文阅读


在加载页面时网页首屏加载时间过长,给用户带来不好的体验,所以我们通常使用加载动画的方式去实现。

加载动画实现原理

首先准备好加载动画和页面内容,之后监听页面的加载状态,如果页面在加载中显示加载动画内容,当页面加载完成后隐藏加载动画部分。

基本实现

1. 创建HTML结构

首先,创建一个基本的HTML结构,包括加载动画的容器和页面内容的容器。

<!DOCTYPE html>  <html lang="en">  <head>      <meta charset="UTF-8">      <meta name="viewport" content="width=device-width, initial-scale=1.0">      <title>加载动画示例</title>      <link rel="stylesheet" href="styles.css">  </head>  <body>      <div id="loader">          <div class="loader-inner"></div>      </div>      <div id="content" class="hidden">          <h1>欢迎来到我的网站</h1>          <p>这里是页面内容...</p>          <!-- 其他页面内容 -->      </div>      <script src="script.js"></script>  </body>  </html>

2. 添加CSS样式

接下来,添加CSS样式来定义加载动画和页面内容的显示方式。

/* styles.css */  body, html {      margin: 0;      padding: 0;      width: 100%;      height: 100%;      overflow: hidden;      font-family: Arial, sans-serif;  }    #loader {      position: fixed;      top: 0;      left: 0;      width: 100%;      height: 100%;      background-color: #fff;      z-index: 9999;      display: flex;      justify-content: center;      align-items: center;  }    .loader-inner {      border: 16px solid #f3f3f3;      border-radius: 50%;      border-top: 16px solid #3498db;      width: 120px;      height: 120px;      animation: spin 2s linear infinite;  }    @keyframes spin {      0% { transform: rotate(0deg); }      100% { transform: rotate(360deg); }  }    #content.hidden {      display: none;  }    #content {      display: flex;      justify-content: center;      align-items: center;      height: 100vh;      text-align: center;      background-color: #f3f3f3;  }
3. 添加JavaScript逻辑

最后,添加JavaScript逻辑来在页面加载完成后隐藏加载动画并显示页面内容。

// script.js  document.addEventListener('DOMContentLoaded', function() {      // 模拟页面加载时间      setTimeout(function() {          // 隐藏加载动画          document.getElementById('loader').classList.add('hidden');          // 显示页面内容          document.getElementById('content').classList.remove('hidden');      }, 2000); // 2秒模拟加载时间,可以根据实际需要调整  });

在vue3中实现


1. 在App.vue中添加加载界面的结构和样式代码。当然写成组件然后在此引入也是可以的。

<template><!-- 加载界面 --><Transition name="loading"><div v-if="loading" class="loader-wrapper"><span class="loader"><span class="loader-inner"></span></span></div></Transition><!-- 主界面 --><router-view></router-view></template>
.loader-wrapper {position: absolute;left: 0;top: 0;height: 100vh;width: 100vw;background-color: white;display: flex;justify-content: center;align-items: center;}.loader {display: inline-block;width: 30px;height: 30px;position: relative;border: 4px solid #42b883;animation: loader 2s infinite ease;}.loader-inner {vertical-align: top;display: inline-block;width: 100%;background-color: #42b883;animation: loader-inner 2s infinite ease-in;}@keyframes loader {0% {transform: rotate(0deg);}25% {transform: rotate(180deg);}50% {transform: rotate(180deg);}75% {transform: rotate(360deg);}100% {transform: rotate(360deg);}}@keyframes loader-inner {0% {height: 0%;}25% {height: 0%;}50% {height: 100%;}75% {height: 100%;}100% {height: 0%;}}.loading-move,.loading-enter-active,.loading-leave-active {transition: all 0.5s ease-in-out;}.loading-enter-from,.loading-leave-to {opacity: 0 !important;}

2. emitter安装和引入。

npm install mitt 

新建utils/emitter.ts。内容如下 

import mitt from 'mitt' const emitter = mitt() export default emitter

3. 使用mitt来注册一个全局事件来控制加载界面的显示与否

现在我们写好了加载界面,不过它一直显示在主界面的上方。我们的需求是在初始加载和首次切换至某个路由时显示加载界面。

import {onUnmounted,ref} from 'vue';import emitter from './utils/emitter.js';const loading = ref(true);// 确保事件处理函数具有正确的类型  const handleLoading = (a) => {loading.value = a;};// 注册控制加载事件  emitter.on('loading', handleLoading);onUnmounted(() => {// 确保 emitter.off 能够正确移除监听器  // 如果 emitter.off 需要特定的回调函数,则使用 handleLoading  emitter.off('loading', handleLoading);});

4. 在router配置文件中添加路由守卫, 并创建一个Set集合用于记录已经访问过的路由

import emitter from '@/utils/emitter' // 创建一个全局状态来管理首次访问状态const visitedRoutes = new Set() // 路由守卫router.beforeEach((to, from, next) => {  if (!visitedRoutes.has(to.path)) {    emitter.emit('loading', true)  }  next()}) router.afterEach((to) => {  if (!visitedRoutes.has(to.path)) {    visitedRoutes.add(to.path)    emitter.emit('loading', false)  }})

在路由守卫中进行处理:

- 访问路由前:如果将要访问的路由不在Set集合中,触发全局事件显示加载界面

- 访问路由后:如果当前路由不在Set集合中,将当前路由的path添加至Set集合中,并触发全局事件隐藏加载界面


点击全文阅读


本文链接:http://zhangshiyu.com/post/182297.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1