如何实现静态HTML页面的加载进度百分比显示?
实现带百分比的页面加载进度条
浏览器并没有原生API能直接获取页面所有待加载资源的总大小,所以没法直接精确计算真实的加载百分比。市面上的进度条大多采用以下两种可行方案:
方案1:视觉模拟进度条(最常用)
这种方案不需要统计真实资源加载量,通过流畅的动画模拟加载进度,最后在页面完全加载时直接跳至100%,用户感知自然,实现成本极低。
实现代码
<!-- 全屏加载遮罩,默认显示 --> <div id="loader" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 9999;"> <div style="width: 60%; height: 4px; background: #eee; border-radius: 2px; overflow: hidden;"> <div id="progress-bar" style="width: 0%; height: 100%; background: #2196F3; transition: width 0.3s ease;"></div> </div> <p id="progress-text" style="margin-top: 16px; font-size: 14px; color: #666;">0%</p> </div> <!-- 页面内容,默认隐藏 --> <div id="content" style="display: none;"> <!-- 你的页面内容,比如图片、文本、脚本等 --> <img src="image1.jpg" alt="示例图1"> <img src="image2.jpg" alt="示例图2"> <script src="script.js"></script> </div> <script> const loader = document.getElementById('loader'); const progressBar = document.getElementById('progress-bar'); const progressText = document.getElementById('progress-text'); const content = document.getElementById('content'); let currentProgress = 0; // 定时递增进度,模拟加载波动 const progressTimer = setInterval(() => { currentProgress += Math.floor(Math.random() * 5) + 1; // 进度停在90%,留到最后加载完成再跳100% if (currentProgress > 90) currentProgress = 90; updateProgress(currentProgress); }, 200); // 更新进度条和文本 function updateProgress(percent) { progressBar.style.width = `${percent}%`; progressText.textContent = `${percent}%`; } // 监听页面所有资源加载完成 window.addEventListener('load', () => { updateProgress(100); // 等待动画完成后隐藏遮罩、显示内容 setTimeout(() => { loader.style.display = 'none'; content.style.display = 'block'; }, 300); clearInterval(progressTimer); }); </script>
说明
这种方式避免了真实加载可能出现的卡顿、停滞问题,用户体验流畅,是绝大多数网站的选择。
方案2:手动统计的真实进度条
如果需要真实反映资源加载进度,需要预先统计所有资源的大小,再逐个监听加载状态计算百分比。
实现代码
<div id="loader" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 9999;"> <div style="width: 60%; height: 4px; background: #eee; border-radius: 2px; overflow: hidden;"> <div id="progress-bar" style="width: 0%; height: 100%; background: #2196F3; transition: width 0.2s ease;"></div> </div> <p id="progress-text" style="margin-top: 16px; font-size: 14px; color: #666;">0%</p> </div> <div id="content" style="display: none;"> <!-- 页面内容容器 --> </div> <script> const loader = document.getElementById('loader'); const progressBar = document.getElementById('progress-bar'); const progressText = document.getElementById('progress-text'); const content = document.getElementById('content'); // 手动维护资源列表:URL + 文件大小(单位:字节) const resources = [ { url: 'image1.jpg', size: 123456 }, { url: 'image2.jpg', size: 789012 }, { url: 'script.js', size: 45678 }, { url: 'style.css', size: 23456 }, // 补充其他需要加载的资源 ]; let totalSize = 0; let loadedSize = 0; // 计算总资源大小 resources.forEach(res => totalSize += res.size); // 更新进度 function updateProgress() { const percent = Math.floor((loadedSize / totalSize) * 100); progressBar.style.width = `${percent}%`; progressText.textContent = `${percent}%`; // 所有资源加载完成 if (percent >= 100) { setTimeout(() => { loader.style.display = 'none'; content.style.display = 'block'; // 这里可以初始化页面逻辑 }, 300); } } // 加载单个资源 function loadResource(resource) { return new Promise((resolve) => { if (resource.url.match(/\.(jpg|png|gif)$/)) { // 加载图片 const img = new Image(); img.onload = img.onerror = () => { loadedSize += resource.size; updateProgress(); resolve(); }; img.src = resource.url; } else if (resource.url.endsWith('.js')) { // 加载脚本 const script = document.createElement('script'); script.onload = script.onerror = () => { loadedSize += resource.size; updateProgress(); resolve(); }; script.src = resource.url; document.body.appendChild(script); } else if (resource.url.endsWith('.css')) { // 加载样式 const link = document.createElement('link'); link.rel = 'stylesheet'; link.onload = link.onerror = () => { loadedSize += resource.size; updateProgress(); resolve(); }; link.href = resource.url; document.head.appendChild(link); } // 其他类型资源(如字体)可同理扩展 }); } // 批量加载所有资源 async function loadAllResources() { for (const res of resources) { await loadResource(res); } } // 启动加载流程 loadAllResources(); </script>
说明
这种方案能实现真实的加载百分比,但需要手动维护资源列表和大小,资源更新时需同步修改;另外如果资源被缓存,可能不会触发加载事件,需要额外处理缓存逻辑。
内容的提问来源于stack exchange,提问作者Manjesh R V
相关产品推荐
相关产品推荐

