JS模拟滚动条
滚动条模拟实在基本JS拖拽基础上的加深。
滚动条需要做的是1.滚动条的拖拽,以及内容滚动高度的改变。2.上下按钮点击效果以及内容高度改变。3.鼠标滚轮在内容中滚动时内容高度改变,以及滚动条的高度改变。
我把这种模拟滚动条分成两类,一类是内容属性为overflow:hidden的,重点在于上文所说的第三点,如果是hidden属性的话,滚轮在页面内容里滚动是不会触发onscroll事件的,需要给鼠标滚轮绑定事件,而鼠标滚轮事件在IE中是onmousewheel,在DOM中是DOMMouseScroll,后者还需要addEventListener来添加,非常的麻烦,这里第二种更加简单易于理解的方法。第二类就是overflow:scroll的,当然只是在JS中内容超过高度或者宽度了再设置X,或Y方向的scroll。这种方法在内容框边上会有个自动生成的滚动条,你可以用背景,或者用你自己做的滚动条样式覆盖上去,这种方法的话上文说的第三点只需要在内容中绑定onscroll事件即可,不必处理浏览器的兼容性。
html:
<div id="news_list" style="height:300px; overflow:hidden">
<div class="news_content" style="height:500px;">
内容
</div>
</div>
<div id="scroll" style="display:none">
<div class="scroll_bar"></div>
<div class="scroll_prev"></div>
<div class="scroll_next"></div>
</div>
为了方便,在选取对象过程中,我直接用了children[i]这种方法,如果大家的html有变化的话,需要改动里面的i值
function scroll(id,id2){
var obj=document.getElementById(id);
var list=document.getElementById(id2);
list.scrollTop=0;
var oUl=list.children[0];
var bar=obj.getElementsByTagName("div")[0];
var prev=obj.getElementsByTagName("div")[1];
var next=obj.getElementsByTagName("div")[2];
if(oUl.offsetHeight>list.offsetHeight){
obj.style.display='block';
list.style.overflowY='scroll';
//按比例设置滚动条长度
bar.style.height=Math.floor(obj.offsetHeight*list.offsetHeight/oUl.offsetHeight)+'px';
bar.style.overflow='hidden';
//拖拽滚动条事件加载
bar.onmousedown=function(ev){
var o=this;
var oEvent=ev||event;
var y=oEvent.clientY-this.offsetTop;
document.onmousemove=function(ev){
oEvent=ev||event;
var otop=oEvent.clientY-y;
var stop=otop*oUl.offsetHeight/obj.offsetHeight;
if(otop<=0){
o.style.top=0+'px';
list.scrollTop=0;
}else if(otop>=obj.offsetHeight-bar.offsetHeight){
o.style.top=obj.offsetHeight-bar.offsetHeight+'px';
list.scrollTop=oUl.offsetHeight-list.offsetHeight;
}else{
o.style.top=otop+'px';
list.scrollTop=stop;
}
}
document.onmouseup=function(){
document.onmousemove=null;
document.onmouseup=null;
}
}
//向上按钮事件加载
prev.onmousedown=function(){
if(bar.offsetTop>0){
var move=setInterval(function(){
if(bar.offsetTop-obj.offsetHeight*0.02>0){
bar.style.top=bar.offsetTop-obj.offsetHeight*0.02+'px';
list.scrollTop=list.scrollTop-oUl.offsetHeight*0.02;
}else{
clearInterval(move);
bar.style.top=0+'px';
list.scrollTop=0;
}
},100);
prev.onmouseup=function(){clearInterval(move);}
}
}
//向下按钮事件加载
next.onmousedown=function(){
if(bar.offsetTop<obj.offsetHeight-bar.offsetHeight){
var move=setInterval(function(){
if(bar.offsetTop+obj.offsetHeight*0.02<obj.offsetHeight-bar.offsetHeight){
bar.style.top=bar.offsetTop+obj.offsetHeight*0.02+'px';
list.scrollTop=list.scrollTop+oUl.offsetHeight*0.02;
}else{
clearInterval(move);
bar.style.top=obj.offsetHeight-bar.offsetHeight+'px';
list.scrollTop=oUl.offsetHeight-list.offsetHeight;
}
},100);
next.onmouseup=function(){clearInterval(move);}
}
}
//鼠标滚轮事件加载
list.onscroll=function(){
bar.style.top=list.scrollTop*obj.offsetHeight/oUl.offsetHeight+'px';
}
}
}
使用方法:
scroll("scroll","news_list");
这只是个易于理解的版本,还有很多可以优化的地方,不如说可以在一开始就求出滚动条和页面的比例值,这样就不用后面反复的计算它们的比例来求另一个的值了。