设计目标:希望复刻浏览器原生竖向滚动条的功能,并且能做一些个性化配置
测试页面:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <script src="MyScrolly.js"></script> 7 </head> 8 <body> 9 <div id="div_allbase" style="width: 800px;height: 600px;background-color: beige;overflow-y: hidden">10 <div id="div_outer" style="width: 700px;height: 500px;background-color: cornflowerblue;overflow-y: auto">11 <div id="div_inner1" style="width: 600px;height: 300px;background-color: darkseagreen">12 11111111111111111111111111111111111111111111111111111111111111113 </div>14 <div id="div_inner2" style="width: 600px;height: 300px;margin-top: 50px;background-color: darkseagreen"">15 22222222222222222222222222222222222222222222222222222222222222216 </div>17 <div id="div_inner3" style="width: 600px;height: 300px;margin-top: 50px;background-color: darkseagreen"">18 33333333333333333333333333333333333333333333333333333333333333319 </div>20 </div>21 </div>22 </body>23 <script>24 var myScroll=new MyScrolly(document.getElementById("div_outer")//要添加滚动条的元素25 ,{parentelem:document.getElementById("div_allbase")})//配置参数26 myScroll.func_count(myScroll);//在innerHTML发生变化或onresize之后重新计算dragbar的长度
//使用这种方式可以为页面中的多个元素配置不同的滚动条样式27 </script>28 </html>代码实现:
1 function MyScrolly(elem,obj_p) 2 { 3 if(elem) 4 { 5 obj_p=obj_p||{}; 6 this.elem=elem; 7 this.func_render=obj_p.func_render||MyScrolly.defaultRender;//滚动条的dom结构 8 this.func_count=obj_p.func_count||MyScrolly.countChildren;//在页面发生变化时滚动条的变化方式 9 this.func_render(elem,this); 10 this.parentelem=obj_p.parentelem||elem;//支持拖拽、释放、禁止选择等动作的外围元素范围,默认设置为document可能效果更好 11 //this.clientY0=this.elem.clientY;//没有用到 12 this.last_clientY=-1; 13 //elem.onload 14 var that=this; 15 //使用页面观察器观察dom变化!!<-兼容性如何??<-html5,并且会导致this被替换为MutationObserver对象,并且不好控制调用条件 16 // var MutationObserver=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver; 17 // //var mo=new MutationObserver(that.countChildren); 18 // var mo=new MutationObserver(function(records){ 19 // that.func_count(that); 20 // }); 21 // this.mo=mo; 22 // var option={ 23 // childList:true, 24 // subtree:true, 25 // } 26 //mo.observe(this.elem,option); 27 28 this.div2.onpointerdown=function (event) {//按下scrollbar 29 that.picked=true; 30 that.last_clientY=event.clientY;//取相对定位的参考点 31 that.parentelem.onselectstart=function(event){//防止在上下滑动时选中div中的文本 32 event.returnValue=false; 33 return false; 34 } 35 } 36 this.parentelem.onpointerup=function (event) { 37 that.picked=false; 38 that.parentelem.onselectstart=null; 39 //that.parentelem.onmousewheel=null; 40 } 41 this.parentelem.onpointerleave=function (event) { 42 that.picked=false; 43 that.parentelem.onselectstart=null; 44 that.parentelem.onmousewheel=null; 45 } 46 this.parentelem.onpointermove=function (event) {//拖动效果在div_allbase范围内均有效 47 if(that.picked==true&&(that.last_clientY>=0)) 48 { 49 //event.preventDefault();//阻止默认的行为发生 50 51 var int_clientY=event.clientY-that.last_clientY;//因为比较难定位elem的初始位置(也许elem自身会发生移动或变形),这里使用相对变化量 52 that.last_clientY=event.clientY; 53 var top_div2=parseInt(that.div2.style.top);//滑块上端到滑轨上端的距离,关于div2等属性的含义见defaultRender方法 54 var int1=top_div2+int_clientY; 55 if((that.outer_height-that.height_scrollbar)<int1) 56 {//如果过于靠下 57 int1=that.outer_height-that.height_scrollbar 58 } 59 if(int1<0) 60 {//如果过于靠上 61 int1=0 62 } 63 64 // if((that.outer_height-that.height_scrollbar)>=(top_div2+int_clientY)&&((top_div2+int_clientY)>=0)) 65 // { 66 that.div2.style.top=int1+"px";//移动滑块 67 var int2=(int1)/(that.outer_height/that.inner_height) 68 that.elem.scrollTop=int2;//滚动元素内容 69 that.div1.style.top=int2+"px";//移动滑轨 70 //console.log(that.elem.scrollTop); 71 // } 72 73 74 } 75 } 76 //this.parentelem.onclick=function(event){ 77 this.parentelem.onmouseenter=function(event){//鼠标滚轮,这里没有兼容火狐 78 that.parentelem.onmousewheel=function(event){ 79 if(that.last_clientY<0) 80 { 81 that.last_clientY=0; 82 } 83 if((that.last_clientY>=0)) 84 { 85 var int_clientY=-event.wheelDelta; 86 var top_div2=parseInt(that.div2.style.top); 87 var int1=top_div2+int_clientY; 88 if((that.outer_height-that.height_scrollbar)<int1) 89 { 90 int1=that.outer_height-that.height_scrollbar 91 } 92 if(int1<0) 93 { 94 int1=0 95 } 96 97 that.div2.style.top=int1+"px"; 98 var int2=(int1)/(that.outer_height/that.inner_height) 99 that.elem.scrollTop=int2;100 that.div1.style.top=int2+"px";101 //console.log(that.elem.scrollTop);102 103 }104 }105 }106 107 }108 else {109 return false;110 }111 112 113 }114 //MyScrolly.prototype115 //计算容器内部组件的实际高度,并就此调整滚动条显示效果116 //MyScrolly.prototype.countChildren=function(records){117 MyScrolly.countChildren=function(that){118 //this=that;119 var arr=that.elem.childNodes;//如果使用MutationObserver,则这里的this是MutationObserver对象!!120 var len=arr.length;121 var sum_height=0;122 // for(var i=0;i<len;i++)//假设除了滚动条之外的所有元素都是纵向排列的!!《-这里需要递归排列!!??123 // {累加元素内部children的高度124 // var obj=arr[i];125 // if(obj.className!="div_myscroll1")126 // {127 // var int=obj.offsetHeight;128 // if(int)//有些textnode的高度可能是undefined!!129 // {130 // sum_height+=int;131 // }132 //133 // }134 // }135 //考虑到margin,换一种测量思路136 for(var i=len-1;i>0;i--)137 {138 var obj=arr[i];139 if(obj.className!="div_myscroll1")140 {141 var int=obj.offsetHeight;142 if(int)//有些textnode的高度可能是undefined!!143 {144 sum_height+=int;145 sum_height+=obj.offsetTop;146 break;147 }148 149 }150 }151 that.inner_height=sum_height;//元素内容高度152 that.outer_height=that.elem.offsetHeight;//元素本身高度153 console.log("重新测量高度"+that.outer_height+"/"+that.inner_height);154 that.div2.style.top="0px";//滑块复位155 that.elem.scrollTop=0;156 that.clientY0=0;157 that.picked=false;158 that.last_clientY=-1;//这里还应该加上取消监听的代码159 if(that.inner_height<=that.outer_height)//如果不需要显示滚动条160 {161 that.div1.style.display="none";162 }163 else {164 that.div1.style.display="block";165 var int=that.outer_height*(that.outer_height/that.inner_height);166 that.height_scrollbar=int;167 that.div2.style.height=int+"px";168 }169 }170 //默认的滚动条样式,也可以在这里使用图片等自定义样式171 MyScrolly.defaultRender=function(elem,that)172 {173 elem.style.position="relative";174 elem.style.overflowX="hidden";175 elem.style.overflowY="hidden";//取消浏览器自带的滚动条176 var div1=document.createElement("div");//滑轨177 div1.className="div_myscroll1";178 div1.style.width="10px";179 div1.style.backgroundColor="rgb(245,245,245)";180 div1.style.position="absolute";181 div1.style.right="0px";182 div1.style.top="0px";183 div1.style.height="100%";184 div1.style.zIndex=elem.style.zIndex+10;185 div1.style.display="none";186 that.div1=div1;187 var div2=document.createElement("div");//滑块188 div2.className="div_myscroll2";189 div2.style.width="10px";190 div2.style.backgroundColor="rgb(226,226,226)";191 div2.style.position="absolute";192 div2.style.right="0px";193 div2.style.top="0px";194 //div1.style.height="100%";195 div2.style.zIndex=elem.style.zIndex+20;196 that.div2=div2;197 div1.appendChild(div2);198 elem.appendChild(div1);199 }
原文转载:http://www.shaoqun.com/a/489689.html
汇通天下物流:https://www.ikjzd.com/w/2055
亚马逊t恤:https://www.ikjzd.com/w/1932
myshow:https://www.ikjzd.com/w/2235
设计目标:希望复刻浏览器原生竖向滚动条的功能,并且能做一些个性化配置测试页面:1<!DOCTYPEhtml>2<htmllang="en">3<head>4<metacharset="UTF-8">5<title>Title</title>6<scriptsrc="MyS
wario:https://www.ikjzd.com/w/887
indiegogo:https://www.ikjzd.com/w/265
听说海南有个圣公石很漂亮,请问是真的吗?:http://tour.shaoqun.com/a/43830.html
暑假去深圳野生动物园有什么好玩的?深圳野生动物园暑期活动?:http://tour.shaoqun.com/a/57812.html
佛冈金龟泉温泉怎样?:http://tour.shaoqun.com/a/2691.html
No comments:
Post a Comment