js实现加载进度条
使用XMLHttpRequest监听进度事件
通过XMLHttpRequest对象的progress事件可以获取文件加载进度。创建一个进度条div,根据事件中的loaded和total属性更新进度条宽度:
const xhr = new XMLHttpRequest();
const progressBar = document.getElementById('progress-bar');
xhr.open('GET', 'large-file.url', true);
xhr.onprogress = (e) => {
if (e.lengthComputable) {
const percent = (e.loaded / e.total) * 100;
progressBar.style.width = `${percent}%`;
}
};
xhr.send();
使用Fetch API配合ReadableStream
Fetch API结合ReadableStream可以实现更现代的进度监控方案。通过读取响应体的流数据计算进度:

fetch('large-file.url')
.then(response => {
const reader = response.body.getReader();
const contentLength = +response.headers.get('Content-Length');
let received = 0;
return new ReadableStream({
start(controller) {
function push() {
reader.read().then(({done, value}) => {
if (done) {
controller.close();
return;
}
received += value.length;
const percent = (received / contentLength) * 100;
updateProgressBar(percent);
controller.enqueue(value);
push();
});
}
push();
}
});
});
页面加载进度模拟
对于页面整体加载进度,可以结合DOM事件模拟进度效果。监听DOMContentLoaded和load事件分阶段更新进度:
window.addEventListener('DOMContentLoaded', () => {
updateProgress(70); // 模拟DOM加载完成70%
});
window.addEventListener('load', () => {
updateProgress(100); // 页面完全加载
});
function updateProgress(percent) {
document.querySelector('.progress-bar').style.width = `${percent}%`;
}
CSS动画作为后备方案
当无法获取真实加载进度时,可以使用CSS动画创建无限循环的进度条效果:

.progress-bar {
animation: progress 2s ease-in-out infinite;
background: linear-gradient(to right, #4cd964, #5ac8fa);
}
@keyframes progress {
0% { width: 0%; }
100% { width: 100%; }
}
分段加载进度计算
对于多资源加载场景,需要跟踪每个资源的加载状态。维护一个加载队列,计算总体进度:
const resources = ['a.jpg', 'b.js', 'c.css'];
let loadedCount = 0;
resources.forEach(url => {
fetch(url).then(() => {
loadedCount++;
const percent = (loadedCount / resources.length) * 100;
updateProgressBar(percent);
});
});
进度条UI组件实现
创建可复用的进度条组件,包含动画和状态管理功能:
class ProgressBar {
constructor(selector) {
this.element = document.querySelector(selector);
this.value = 0;
}
setValue(percent) {
this.value = Math.min(100, Math.max(0, percent));
this.element.style.width = `${this.value}%`;
}
complete() {
this.setValue(100);
setTimeout(() => this.element.style.opacity = 0, 500);
}
}






