滚动条的基本交互有两个,鼠标拖拽滚动条和滚轮滚动。
滚动条涉及到的dom元素:1、主体区域(obj,box2与box4的父元素),鼠标滚动的触发主体,包含内容和滚动条,宽高自定。2、滚动条(box1),宽自定,高按内容区比例计算。3、滚动区域(box2,box1的父节点),高与内容可视区的高相同,宽自定。4、内容(box3,滚动的内容主体)。5、内容(box4,box3的父元素,有限宽高,内容可视区)。
实现的基本原理就是以上元素绝对定位,通过鼠标的交互事件,来完成相关dom的top值,已达到模拟滚动条的目的。
function scrollbar(obj,box1,box2,box3,box4){
var oBox=document.getElementById(obj);
var oBar=document.getElementById(box1);
var oRight=document.getElementById(box2);
var oCon=document.getElementById(box3);
var oLeft=document.getElementById(box4);
//算滚动快的高度
oBar.style.height=oLeft.offsetHeight/oCon.offsetHeight*oRight.offsetHeight+‘px‘;
//添加滚动快拖动的事件
oBar.onmousedown=function(ev){
var oEvent=ev || event;
console.log(oEvent.clientY);
var disY=oEvent.clientY-oBar.offsetTop;
document.onmousemove=function(ev){
var oEvent=ev || event;
var t=oEvent.clientY-disY;
setTop(t);
}
document.onmouseup=function(){
document.onmousemove=null;
document.onmouseup=null;
oBar.releaseCapture && oBar.releaseCapture();
}
oBar.setCapture && oBar.setCapture();
return false;
}
function setTop(t){
t<0 && (t=0);
t>oRight.offsetHeight-oBar.offsetHeight&&(t=oRight.offsetHeight-oBar.offsetHeight);
oBar.style.top=t+‘px‘;
var scale=t/(oRight.offsetHeight-oBar.offsetHeight);
oCon.style.top=-(oCon.offsetHeight-oLeft.offsetHeight)*scale+‘px‘;
}
}
函数setTop为主要交互函数,主要是根据传入的参数改变内容和滚动块的top值,完成模拟滚动。
以上函数完成了滚动的拖动交互,下面的函数完成滚轮滚动
function addWheel(obj,fn){
function fnWheel(ev){
var oEvent=ev || event;
var bDown=false;
if(oEvent.wheelDelta){
if(oEvent.wheelDelta<0){
bDown=true;
}else{
bDown=false;
}
}else{
if(oEvent.detail>0){ //ff浏览器
bDown=true;
}else{
bDown=false;
}
}
fn && fn(bDown);
oEvent.preventDefault && oEvent.preventDefault();
return false;
}
//ff浏览器滚动事件特殊
if(window.navigator.userAgent.toLowerCase().indexOf(‘firefox‘)!=-1){
obj.addEventListener(‘DOMMouseScroll‘,fnWheel,false);
}else{
obj.onmousewheel=fnWheel;
}
}
addWheel(oBox,function(bDown){
var t=oBar.offsetTop;
if(bDown){
t+=10;
}else{
t-=10;
}
setTop(t);
});
把addWheel函数放入scrollbar中,滚动的速度可以由回调函数的参数t控制。
通过调用scrollbar函数就能简单完成模拟滚动条的功能(垂直)。
原文:http://my.oschina.net/bothyan/blog/504536