自写JS模拟滚动条实现插件(支持触摸)
作者:秋了秋 发表时间:2016年03月10日
最近做项目的时候,遇到比较多局部滚动的需求,本来想偷懒直接在外层div加个css样式overflow:auto;就可以实现滚动,可是后来发现默认滚动条实在是太丑,尤其在mac的chrome和ie上,而且局部滚动的时候连同页面也在滚动。这种体验,只要有人测试,都会提出修改的建议,可是默认的无从修改,即使修改了样式也存在兼容性。除非自写方法,用js取代默认滚动方法。
为了以后的省事,干脆用个插件算了,可是网上找了一些插件,看了下效果,大部分都写得有bug,要不就是无法运用,要不就是不支持移动触摸,要不就是不会运用,通用性不强,也没仔细讲使用方法和注意事项,一气之下就自己写了个自己认为比较满意的方法。以下是方法:
(function(){
function scrollFn(scrollContain,scrollContent,scrollbar){
var scloll=0;
var $scrollContent=document.getElementById(scrollContent),
$scrollHeight=$scrollContent.offsetHeight;
var $iframe=document.getElementById(scrollContain),
$iframeHeight=$iframe.offsetHeight;
if(scrollbar){
var $scrollbar=document.getElementById(scrollbar);
$scrollbar.style.height=$iframeHeight*$iframeHeight/$scrollHeight+"px";
var $scrollbarHeight=$scrollbar.offsetHeight;
if($scrollbarHeight>=$iframeHeight){
$scrollbar.style.display="none";
}
}
$iframe.style.overflow="hidden";
$iframe.style.position="relative";
$scrollContent.style.position="absolute";
function scrollFunc(e){
var e=e||window.event;
$scrollHeight=$scrollContent.offsetHeight;
var wheelValue=e.wheelDelta/120||-e.detail;
var dir=wheelValue>0?"up":"down";
if(dir=="up"){scloll+=80;}else{scloll-=80;}
if(Math.abs(scloll)>$scrollHeight-$iframeHeight){
scloll=-$scrollHeight+$iframeHeight;
}
if(scloll>0){scloll=0;}
$scrollContent.style.top=scloll+"px";
var $percent=Math.abs(scloll)/($scrollHeight-$iframeHeight);
var $scrolllength=$iframeHeight-$scrollbarHeight;
if(scrollbar){
$scrollbar.style.top=$percent*$scrolllength+"px";
}
e.preventDefault();
return false;
}
//滑块滚动
if(scrollbar){
$scrollbar.style.opacity=0.8;
$iframe.onmouseover=function(){
$scrollbar.style.opacity=1;
}
$iframe.onmouseout=function(){
$scrollbar.style.opacity=0.8;
}
$scrollbar.onmousedown=function(e){
var objY=this.offsetTop;
var e=e||window.event;
var y=e.clientY;
var realY=y-objY;
var _this=this;
$scrollHeight=$scrollContent.offsetHeight;
document.onmousemove=function(e){
var e=e||window.event;
var y1=e.clientY;
var realY2=y1-realY;
if(realY2<0){realY2=0;}else if(realY2>$iframeHeight-$scrollbarHeight){
realY2=$iframeHeight-$scrollbarHeight;
}
_this.style.top=realY2+"px";
$scrollContent.style.top=-realY2/($iframeHeight-$scrollbarHeight)*($scrollHeight-$iframeHeight)+"px";
e.preventDefault();
return false;
}
document.onmouseup=function(){
document.onmousemove=null;
document.onmouseup=null;
}
}
}
if(document.addEventListener){
$iframe.addEventListener('DOMMouseScroll',scrollFunc,false);
}
$iframe.onmousewheel=scrollFunc;
//移动端触摸滚动
(function(){
var x,y,begin_top;
$iframe.addEventListener("touchstart",function(e){
var e=e||window.event;
var touch = e.touches[0];
y = parseInt(touch.clientY);
begin_top=$scrollContent.offsetTop;
$scrollHeight=$scrollContent.offsetHeight;
},false);
$iframe.addEventListener("touchmove",function(e){
var e=e||window.event;
e.preventDefault();
var touch = e.touches[0];
y1 = parseInt(touch.clientY);
$scrollContent.style.top=begin_top+(y1-y)+"px";
if($scrollContent.offsetTop>0){
$scrollContent.style.top=0;
}else if($scrollContent.offsetTop<-($scrollHeight-$iframeHeight)){
$scrollContent.style.top=-($scrollHeight-$iframeHeight)+"px";}
},false);
})()
}
})();
使用方法:
scrollFn("data-move","data-movecontent","scrollbar2");
对应的data-move是外层容器id名字,data-movecontent是内容容器id名字,scrollbar2是滚动条id名字。 html例子:
<div id="data-move"> <div id="data-movecontent">这个事件在标准下和IE下是有区别的。 firefox是按标准实现的,事件名为"DOMMouseScroll ",IE下采用的则是"mousewheel "。 当然一行代码就解决了兼容问题 </div> <i id="scrollbar2"></i> </div>
css就自己写了,这里不啰嗦,主要讲一讲注意事项:
1.每一个局部滚动都只需要通过调用方法scrollFn(),通过传参指定id值, 2.注意这三个值必须是id值,不带#,不能为class。 3.外层容器必须css声明position为relative或absolute。 4.只传两个参数也是可以的,即后面那个滚动条id可以不要。 5.外容器必须小于内容高度,否则你也没必要用滚动条吧~ 6.滚动条指定样式:width:5px;height:40px;display:block;background:gray;position:absolute;right:0;top:0;大小颜色这些可以自己修改。 如有任何问题,欢迎联系讨论QQ1183238717,群184139138。