JavaScript 博客内容阅读进度条插件实现详解
本文详细介绍了一款基于 JavaScript 的博客内容阅读进度条插件的实现方案。通过监听页面滚动事件,计算当前滚动距离与文章总高度的比例,动态更新 HTML5 progress 元素的值以显示进度。文章涵盖了核心算法、IE9-浏览器的兼容处理、CSS 样式固定定位以及动态生成 DOM 的完整代码逻辑,帮助开发者快速集成该功能。
博客阅读进度条插件概述
前言
在回顾个人博客文章时,常遇到篇幅极长的内容,导致读者难以预估阅读时长,从而产生畏难情绪。若能引入一个博客内容进度插件,根据阅读进度实时显示进度条,帮助读者掌握阅读状态,将有助于缓解焦虑,鼓励用户逐步完成阅读。本文将深入解析该进度插件的具体实现过程。
功能效果演示
效果演示
无论用户通过鼠标滚轮、拖动滚动条还是按下空格键进行页面滚动,页面底部的博客内容进度条都会随之变化。系统根据当前已读内容与博客总内容的比例,计算出对应的进度条宽度。当鼠标悬停在进度条区域时,会以数字形式展示当前的进度百分比。
使用以下代码即可将进度插件插入到页面中:
<script src="http://files.cnblogs.com/files/xiaohuochai/progress.js"></script>
鉴于目录导航和阅读进度均为常见功能,此处将进度条功能整合至原有的目录生成插件中。
<script src="http://files.cnblogs.com/files/xiaohuochai/catalog.js"></script>
核心算法与原理解析
原理解释
前文已简述进度条的基本原理,其实现并不复杂。核心在于监听滚动事件时计算两个关键高度值:H 表示整篇博客内容底部距离页面顶部的距离,h 表示当前窗口可视区域内博客内容底部距离页面顶部的距离(即滚动偏移量)。由此得出的比例值 radio = h/H 即为进度百分比,通过改变进度条宽度来直观展示。
具体实现步骤与代码
具体实现
【1】获取博客内容总高度 H。如截图所示,博客园将文章主体置于 id 为 cnblogs_post_body 的 div 容器中,通过 scrollHeight 属性即可获取其高度。该值为固定值,无需在每次滚动事件中重新计算,页面加载完成后获取一次即可。


function addEvent(target,type,handler){
if(target.addEventListener){
target.addEventListener(type,handler,false);
}else{
target.attachEvent('on'+type,function(event){
return handler.call(target,event);
});
}
}
var H;
addEvent(window,'load',function(){
H = cnblogs_post_body.scrollHeight;
});
【2】获取当前页面窗口中显示的博客内容高度 h。实际上,h 的值等同于页面的滚动距离 h2,可通过 document.documentElement.scrollTop 或 document.body.scrollTop 获取。
var h = document.documentElement.scrollTop || document.body.scrollTop;
【3】进度条实现。利用 H 和 h 计算出比例系数 radio = h/H。HTML5 新增了一个表单类控件 progress,专门用于表示任务或进程的进度。
[注意] IE9 及以下浏览器不支持 progress 元素。
<progress id="progress" value="" max=""></progress>
针对 IE9 及以下浏览器,progress 元素会被降级为 div 元素,此时仅显示百分比文本即可。
将 progress 元素的 max 属性设置为 H,value 属性设置为 h。在触发滚动事件时,只需更新 value 值即可实现进度变化。
addEvent(window,'scroll',function(){
var h = document.documentElement.scrollTop || document.body.scrollTop;
progress.value = h;
var radio = (h/H >= 1) ? 1 : h/H;
progress.innerHTML = progress.title = Math.floor(100*radio) + '%';
});
【4】样式设置
进度条的样式设置相对简单,主要采用固定定位(position: fixed),使其始终位于页面底部,且宽度与窗口宽度保持一致。
.progress{
position:fixed;
left:0;
right:0;
bottom:0;
width:100%;
height:12px;
text-align:center;
font:12px/12px "宋体";
}
【5】动态脚本
由于最终将以插件形式交付,所有 DOM 元素和事件绑定代码均需动态生成。
var progress = document.createElement('progress');
progress.id = 'progress';
document.body.appendChild(progress);
插件代码
//事件兼容
function addEvent(target,type,handler){
if(target.addEventListener){
target.addEventListener(type,handler,false);
}else{
target.attachEvent('on'+type,function(event){
return handler.call(target,event);
});
}
}
//生成元素
var progress = document.createElement('progress');
progress.id = 'progress';
progress.style.cssText = 'position:fixed;left:0;right:0;bottom:0;width:100%;height:12px;text-align:center;font:12px/12px "宋体";';
document.body.appendChild(progress);
//计算H
var H;
addEvent(window,'load',function(){
progress.max = H = cnblogs_post_body.scrollHeight;
});
//计算h及radio
addEvent(window,'scroll',function(){
var h = document.documentElement.scrollTop || document.body.scrollTop;
progress.value = h;
var radio = (h/H >= 1) ? 1 : h/H;
progress.innerHTML = progress.title = Math.floor(100*radio) + '%';
});
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持本站!
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
D3.js 与 ECharts 选型对比:灵活性 vs 开发效率
2026-11-05 09:45:01
为什么JS中typeof []返回object:数组类型检测误区解析
2026-11-04 19:50:47
