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

前端加载动画效果的实现

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

加载动画实现原理

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

基本实现

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://www.kler.cn/news/357638.html

相关文章:

  • Maven的进阶
  • 从源码到应用:多商户商城系统与直播带货APP的开发详解
  • 大数据治理--技术平台与工具
  • YOLOv10和Ollama增强OCR简要流程
  • node.js 搭建一个直播功能 rtsp 代理
  • docker环境安装mongoDB实现平滑迁移实战
  • 写一段代码判断素数的函数,从主函数中输出一个整数,判断它是否为素数。
  • Linux——vi/vim 编辑器
  • Java中的日期类
  • 鸿蒙应用开发实战-基础语法-变量声明
  • TF-A(Trusted Firmware-A)及其启动流程详解:以stm32MP1平台为例
  • (悬臂)梁结构固有频率理论求解
  • 配合工具,快速学习与体验electron增量更新
  • 探索儿童自闭症康复的奥秘与乐趣
  • 智能家居照明新宠首发:内置降压FP7132调光曲线平滑多路共阳无频闪IC引领未来照明趋势
  • 嵌入式入门学习——6Protues点亮数码管,认识位码和段码,分辨共阴还是共阳(数字时钟第一步)
  • C语言初阶小练习2(三子棋小游戏的实现代码)
  • 【HTML】构建网页的基石
  • Redis高可用与分布式方案实战指南
  • 浙大数据结构:11-散列4 Hashing - Hard Version