[1]效果演示 [2]原理解釋 [3]具體實現 [4]插件代碼 ...
前面的話
最近在複習自己寫的博客,但有的博客內容很長,長到不知道多少時間可以讀完。這時,就有種泄氣的衝動。但,如果能夠提供一個博客內容進度的插件,根據所讀內容的多少,顯示進度條,讓自己對所讀的內容進度心裡有數,可以讓自己平靜下來,一點一點讀下去。本文將詳細介紹博客內容進度插件的實現
效果演示
無論是通過滑鼠滾輪,還是拖動滾動條,也或者是按空格鍵,只要發生了頁面的滾動操作,就會觸發頁面底部博客內容進度條的變化。根據當前內容的多少計算與博客所有內容的比例,最終對應成進度條的寬度。當滑鼠移入進度條範圍時,會以數字顯示出當前的進度百分比
通過使用如下代碼,可將進度插件插入頁面中
<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
var h = document.documentElement.scrollTop || document.body.scrollTop;
【3】進度條實現,通過H和h,可以計算出比例繫數radio = h/H。HTML5新增了一個表單類控制項progress,就是用來表示任務的進度或進程的
[註意]IE9-瀏覽器不支持
<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】樣式設置
進度條的樣式設置較為簡單,將其固定定位,居於頁面底部,並與視窗寬度相同
.progress{ position:fixed; left:0; right:0; bottom:0; width:100%; height:12px; text-align:center; font:12px/12px "宋體"; }
【5】動態腳本
由於最終將以插件的形式呈現,所有的代碼都需要動態生成
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) + '%'; });