css和js实现虚拟滚动条

场景:在开发某个需求时,产品提出卡券横向滚动时原有滚动条太丑,让UI设计了个小滚动条,当卡券滑动时,该小滚动条也可以跟着滚动
想法:一开始是想通过css实现滚动条的样式变化,用::-webkit-scrollbar 相关属性达到更改滚动条的目的,但是用这种方式没法控制横向滚动条的宽度,达不到产品的要求。
解决:纯css是没法实现了,只能通过css和js实现。
html: 先写个ul嵌套li模拟滚动卡券的效果,同级增加一个虚拟滚动条div,该div内嵌一个div(scrollBar)代表滚动的滑块;

<ul class="scrollReal" id="scrollReal" @touchmove="slideMove()">
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>
<div class="scrollFake">
    <div class="scrollBar" :style="{left:slideIconLeft+'px'}"></div>
</div>

css: 先写虚假滚动条的样式,left是个变量,用js实现left的变化

.scrollReal{
  width: 300px;
  overflow-x: scroll;
  white-space: nowrap;
}
.scrollReal li{
  display: inline-block;
  width: 110px;
  height: 100px;
  border: 1px solid #ccc;
  margin-right: 10px;
}
.scrollFake{
  width: 200px;
  height: 20px;
  border-radius: 10px;
  position: relative;
  border: 1px solid #ccc;
}
.scrollBar{
  position: absolute;
  height: 100%;
  width: 30px;
  border-radius: 10px;
  left: 0;
  background: pink;
}

js: 实现虚拟滚动条滑块的滚动,通过改变left的值实现。
1、如上面的html所示,ul的宽度是固定的,li累加起来是卡片总宽度包括margin值,滑动的比例scale为ul左移偏移量scrollLeft除以(卡片总宽度-ul宽度),当ul偏移量scrollLeft==卡片总宽度-ul宽度)时,就代表滑到尽头了。
2、滑动的left的值为scale*虚拟滚动条的宽度,有一点要注意:如果滑动到了(虚拟滚动条的宽度-滑块的宽度),就可以固定left的值为(虚拟滚动条的宽度-滑块的宽度),这样就不会出现滑块溢出的情况。

// 滑块动态left值
var slideLeft = 0;
//动态计算滑块left
slideMove(){
  //虚拟滚动条的总宽度,滑块宽度,css中设置的值
  var slideTotal=200, slideIcon=30;
  //卡片总宽度+margin,css中设置的值
  var liTotalWidth = 110*4+10*4;
  //ul
  var dom=document.getElementById('scrollReal');
  //滑动的比例,ul左偏移量/(卡片总宽度-ul宽度)
  var scale=dom.scrollLeft/(liTotalWidth-dom.offsetWidth);
  //当前虚拟滚动条滑块的left大小,以同等比例*虚拟滚动条总宽度,就可以实现同步滑动
  this.slideLeft = scale*slideTotal;
  //如果滑动到了(虚拟滚动条的宽度-滑块的宽度),就固定left为(虚拟滚动条的宽度-滑块的宽度)
  if(this.slideLeft >= slideTotal-slideIcon){
    this.slideLeft = slideTotal-slideIcon;
  }
}
posted @ 2022-08-30 21:02  阿伊的碎碎念  阅读(967)  评论(0编辑  收藏  举报