vue实现自定义滚动条
具体效果如下,这边我用的rem单位,比例是1:40,
先写下页面布局,把原生的滚动条给隐藏掉,给自定义的滑块增加transition: marginLeft 1s linear;可以使左边距过度的更顺滑
. top- box- 2 : : - webkit- scrollbar {
height : 0 ;
}
< div class = "wrap" >
< ! -- 滚动窗口 -- >
< div
class = "top-box-2"
@scroll= "onScroll"
ref= "box1"
>
< div
class = "top-item"
v- for = "(item,index) in 6"
: key= "index"
> < / div>
< / div>
< ! -- 自定义滚动条 -- >
< div
class = "bar"
ref= "bar"
>
< ! -- 滚动滑块 -- >
< span
ref= "barInner"
: style= "{
'margin-left' : barLeft+ 'px'
} "
> < / span>
< / div>
< / div>
首先我们要先获取滚动窗口的滚动百分比
this . diff = this . $refs. box1. scrollWidth - this . $refs. box1. clientWidth;
this . barWidth =
this . $refs. bar. clientWidth - this . $refs. barInner. clientWidth;
然后获取滚动盒子的百分比,然后设置自定义滚动条滑块的左边距
this . radio = Math. ceil ( ( e. target. scrollLeft * 100 ) / this . diff) ;
this . barLeft = this . barWidth * ( this . radio / 100 ) ;
下面是完整的代码
< template>
< div class = "wrap" >
< ! -- 滚动窗口 -- >
< div
class = "top-box-2"
@scroll= "onScroll"
ref= "box1"
>
< div
class = "top-item"
v- for = "(item,index) in 6"
: key= "index"
> < / div>
< / div>
< ! -- 自定义滚动条 -- >
< div
class = "bar"
ref= "bar"
>
< ! -- 滚动滑块 -- >
< span
ref= "barInner"
: style= "{
'margin-left' : barLeft+ 'px'
} "
> < / span>
< / div>
< / div>
< / template>
< script>
export default {
data ( ) {
return {
diff : 0 ,
scrollLeft : 0 ,
radio : 0 ,
barLeft : 0 ,
barWidth : 0 ,
barInnerWidth : 0 ,
} ;
} ,
mounted ( ) {
setTimeout ( ( ) => {
this . $nextTick ( ( ) => {
this . init ( ) ;
} ) ;
} , 2000 ) ;
} ,
methods : {
init ( ) {
this . diff = this . $refs. box1. scrollWidth - this . $refs. box1. clientWidth;
this . barWidth =
this . $refs. bar. clientWidth - this . $refs. barInner. clientWidth;
} ,
onScroll ( e ) {
this . radio = Math. ceil ( ( e. target. scrollLeft * 100 ) / this . diff) ;
this . barLeft = this . barWidth * ( this . radio / 100 ) ;
} ,
} ,
} ;
< / script>
< style lang= 'scss' scoped>
. wrap {
. top- box- 2 : : - webkit- scrollbar {
height : 0 ;
}
. top- box- 2 {
display : flex;
height : 5rem;
overflow- x: scroll;
margin : 0 2rem;
. top- item {
flex- shrink: 0 ;
width : 4rem;
height : 3rem;
border : 0 . 04rem solid red;
margin : 0 . 5rem;
box- sizing: border- box;
& : first- child {
margin : 0 . 5rem 0 . 5rem 0 . 5rem 0 ;
}
& : last- child {
margin : 0 . 5rem 0 0 . 5rem 0 . 5rem;
}
}
}
. bar {
width : 3rem;
border- radius: 0 . 5rem;
height : 0 . 5rem;
border : 0 . 02rem solid red;
margin : 0 auto;
span {
display : block;
width : 0 . 8rem;
height : 0 . 5rem;
background : blueviolet;
border- radius: 0 . 5rem;
transition : marginLeft 1s linear;
}
}
}
< / style>