2020-11-10

JavaScript实现竖向滚动条的一种思路

设计目标:希望复刻浏览器原生竖向滚动条的功能,并且能做一些个性化配置

测试页面:

 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