【概述】几乎每个企业都有自己的核心东西或说是框架性的东西,框架的好处是将我们经常要使用的功能,控件等包装一个个
易于使用的单元,就算是初学者也极其容易上手,减少项目的开发成本。因此框架的重要性和好处是不言而喻的。在我的这个系列
(一点一滴打造我们自己的web开发框架系列 )当中,我将自己在开发过程中用到的一些东西陆续公布出来,和大家一起交流学习。
这次我们接着本框架系统的开发进展,开发一个web页面上的滚动条。常常在我们的系统中,当我们需要长时间加载数据的时候,
我们希望有个滚动条,或者是弹出一个loading...的窗口,来提示用户你请求的数据正在加载,从而为用户带来较好的用户体验。我们
这次的开发任务正如我的标题一样,开发一个滚动条。至于窗口,我们放在我的系列的下下篇文章中和大家一起来开发。
我们先探讨一下,滚动条的开发需求。当然我们需要一个构造函数,然后我们需要show和hide两个主要的方法来显示和隐藏滚动条,
同时我们还需要几个辅助方法_createProgressBar来创建滚动条div的容器及对后面页面的遮罩效果。我们还需要_getIntervalTick
根据你设定的滚动条的存活时间来算出每次interval时间激发的时间间隔。另外,滚动条递增的宽度可能是小数,这时我们需要一个
_round函数来取整数,最后我们需要dispose来释放一些占用的资源。因为一个页面一个滚动条就够了,因此我们用window.Progress
来存储这个唯一的滚动条。
接下来我们一个个方法来实现
构造函数:

this.Timer = null;
this.Width = typeof (width) == 'undefined' ? 360 : width;
this.Height = typeof (height) == 'undefined' ? 60 : height;
this.AliveSeconds = typeof (aliveSeconds) == 'undefined' ? 10 : aliveSeconds;
this.TickWidth = typeof (tickWidth) == 'undefined' ? 2 : tickWidth;
this.CompleteEvent = null;
this.TipMessage = "数据正在加载中......";
this._outer = null;
this._inner=null;
this._progrss = null;
this._innerDown = null;
this._mark = null;
}
其他方法:

initialize: function() {
},
_createProgressBar: function() {
var outer = document.createElement("DIV");
var inner = document.createElement("DIV");
var innerDown = document.createElement("DIV");
var prs = document.createElement("DIV");
var mask = document.createElement("DIV");
prs.style.backgroundColor = "#467ef0";
prs.style.width = "10px";
prs.style.padding = "0px 0px 0px 0px";
prs.style.margin = "0px 0px 0px 0px";
outer.style.width = this.Width + "px";
outer.style.height = this.Height + "px";
outer.style.backgroundColor = "#E7FDFE";
outer.style.border = "solid #022B2D 1px";
outer.style.position = "absolute";
outer.style.zIndex = "1000";
outer.style.padding = "0px 0px 0px 0px";
outer.style.margin = "0px 0px 0px 0px";
outer.style.left = (document.documentElement.clientWidth - this.Width) / 2 + "px";
outer.style.top = (document.documentElement.clientHeight - this.Height) / 2 + "px";
outer.style.filter = "Alpha(opacity=95)";
inner.style.width = (this.Width - 20) + "px";
inner.style.height = "23px";
inner.style.padding = "0px 0px 0px 0px";
inner.style.margin = "10px 10px 0px 10px";
inner.style.backgroundColor = "#ffffff";
inner.style.border = "solid #022B2D 1px";
innerDown.style.width = inner.style.width;
innerDown.style.height = "23px";
innerDown.style.padding = "0px 0px 0px 0px";
innerDown.style.margin = "3px auto";
innerDown.style.textAlign = "center";
innerDown.style.fontSize = "14px";
innerDown.style.fontWeight = "bold";
innerDown.style.color = "#710425";
prs.style.height = inner.style.height;
mask.style.width = document.documentElement.clientWidth + "px";
mask.style.height = document.documentElement.clientHeight + "px";
mask.style.backgroundColor = "#000000";
mask.style.position = "absolute";
mask.style.zIndex = "500";
mask.style.padding = "0px 0px 0px 0px";
mask.style.margin = "0px 0px 0px 0px";
mask.style.left = "0px";
mask.style.top = "0px";
mask.style.filter = "Alpha(opacity=65)";
mask.style.display = "none";
inner.appendChild(prs);
outer.appendChild(inner);
outer.appendChild(innerDown);
document.body.appendChild(outer);
document.body.appendChild(mask);
this._outer = outer;
this._inner = inner;
this._progrss = prs;
this._innerDown = innerDown;
this._mark = mask;
window.Progress = this;
var tick = this._getIntervalTick();
this.Timer = setInterval(this._graduallyChanging, tick);
},
_getIntervalTick: function() {
var totalWidth = this._inner.style.pixelWidth;
var currentWidth = this._progrss.style.pixelWidth;
var tick = this._round(this.AliveSeconds * 1000 * this.TickWidth / (totalWidth - currentWidth), 0);
return tick;
},
_graduallyChanging: function() {
var totalWidth = window.Progress._inner.style.pixelWidth;
var currentWidth = window.Progress._progrss.style.pixelWidth;
var percent = window.Progress._round(currentWidth * 100 / totalWidth, 0);
if (currentWidth < totalWidth) {
window.Progress._progrss.style.width = currentWidth + window.Progress.TickWidth + "px";
window.Progress._innerDown.innerText = window.Progress.TipMessage + percent + "%";
window.Progress._mark.style.display = "block";
}
else {
if (window.Progress.CompleteEvent != null) {
if (typeof window.Progress.CompleteEvent == 'function')
window.Progress.CompleteEvent.call();
else
eval(window.Progress.CompleteEvent);
}
window.Progress._mark.style.display = "none";
}
},
_round: function(number, pos) {
var n = new Number(number);
var s = Math.pow(10, pos) * n;
var t = Math.round(s);
return t / Math.pow(10, pos);
},
show: function() {
if (window.Progress != null) {
window.Progress.hide();
}
this._createProgressBar();
},
hide: function() {
if (this._outer != null) {
if (this._outer.parentNode != null) {
this._outer.parentNode.removeChild(this._outer);
}
}
if (this._mark != null) {
if (this._mark.parentNode != null) {
this._mark.parentNode.removeChild(this._mark);
}
}
this.dispose();
},
dispose: function() {
clearInterval(this.Timer);
this.Timer = null;
this._outer = null;
this._inner = null;
}
};
写好后,我们在页面上实际测试一下:
包含我们刚写的progressbar.js,
测试的html:
<input type="button" value="显示滚动条" onclick="sh()" />
<input type="button" value="隐藏滚动条" onclick="hide()" />
</div>
添加相关JavaScript事件:

var progress = new ProgressBar();
function sh() {
progress.AliveSeconds = 2;
progress.CompleteEvent = hide;
progress.show();
}
function hide() {
progress.hide();
}
</script>
最后我们来帖个图,看看实际运行的效果:
在我的下一篇文章中,我们将把它包装成服务器控件,方便大家的使用,欢迎关注与指正!(不提供源码下载,要学东西就勤快一点吧)