js实现loading
实现基础Loading动画
使用CSS和JavaScript创建一个简单的旋转动画。通过动态添加/移除类名控制显示隐藏:
<div class="loading-spinner" id="loader"></div>
<style>
.loading-spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
display: none;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
<script>
function showLoader() {
document.getElementById('loader').style.display = 'block';
}
function hideLoader() {
document.getElementById('loader').style.display = 'none';
}
// 使用示例
showLoader();
// 异步操作完成后
setTimeout(hideLoader, 2000);
</script>
页面加载进度条
实现顶部进度条效果,模拟页面加载进度:
<div class="progress-container">
<div class="progress-bar" id="progressBar"></div>
</div>
<style>
.progress-container {
width: 100%;
height: 4px;
background: #f1f1f1;
position: fixed;
top: 0;
left: 0;
z-index: 9999;
}
.progress-bar {
height: 100%;
background: #4CAF50;
width: 0%;
transition: width 0.3s;
}
</style>
<script>
let progress = 0;
const progressBar = document.getElementById('progressBar');
function simulateProgress() {
const interval = setInterval(() => {
progress += Math.random() * 10;
progressBar.style.width = `${progress}%`;
if (progress >= 100) {
clearInterval(interval);
progressBar.style.opacity = '0';
setTimeout(() => {
progressBar.parentElement.remove();
}, 300);
}
}, 300);
}
window.addEventListener('load', simulateProgress);
</script>
异步请求Loading状态
为AJAX请求添加全局Loading指示器:
// 使用Fetch API示例
document.addEventListener('DOMContentLoaded', () => {
const loadingIndicator = document.createElement('div');
loadingIndicator.className = 'global-loading';
document.body.appendChild(loadingIndicator);
// 拦截所有fetch请求
const originalFetch = window.fetch;
window.fetch = async (...args) => {
loadingIndicator.style.display = 'block';
try {
const response = await originalFetch(...args);
return response;
} finally {
loadingIndicator.style.display = 'none';
}
};
});
<style>
.global-loading {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
display: none;
justify-content: center;
align-items: center;
z-index: 9999;
}
.global-loading::after {
content: '';
width: 50px;
height: 50px;
border: 5px solid #fff;
border-top-color: transparent;
border-radius: 50%;
animation: spin 1s linear infinite;
}
</style>
骨架屏加载效果
创建内容加载前的骨架屏占位:
<div class="skeleton-container" id="skeleton">
<div class="skeleton-header"></div>
<div class="skeleton-line"></div>
<div class="skeleton-line"></div>
<div class="skeleton-line"></div>
</div>
<style>
.skeleton-container {
width: 100%;
padding: 20px;
}
.skeleton-header {
height: 100px;
background: #e0e0e0;
margin-bottom: 20px;
border-radius: 4px;
animation: pulse 1.5s ease-in-out infinite;
}
.skeleton-line {
height: 20px;
background: #e0e0e0;
margin-bottom: 10px;
border-radius: 4px;
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
</style>
<script>
// 数据加载完成后
function hideSkeleton() {
document.getElementById('skeleton').style.display = 'none';
}
// 模拟数据加载
setTimeout(hideSkeleton, 2500);
</script>
自定义SVG Loading动画
使用SVG创建更复杂的加载动画:
<div class="svg-loader">
<svg viewBox="0 0 50 50">
<circle cx="25" cy="25" r="20" fill="none" stroke="#3498db" stroke-width="4"></circle>
</svg>
</div>
<style>
.svg-loader {
width: 100px;
height: 100px;
margin: 0 auto;
}
.svg-loader svg {
animation: rotate 2s linear infinite;
}
.svg-loader circle {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
animation: dash 1.5s ease-in-out infinite;
}
@keyframes rotate {
100% { transform: rotate(360deg); }
}
@keyframes dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35;
}
100% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124;
}
}
</style>






