vue实现自定义滚动条
具体效果如下,这边我用的rem单位,比例是1:40,
先写下页面布局,把原生的滚动条给隐藏掉,给自定义的滑块增加transition: marginLeft 1s linear;可以使左边距过度的更顺滑
. top- box- 2 : : - webkit- scrollbar { height : 0 ; }
< div class = "wrap" > < ! -- 滚动窗口 -- > < divclass = "top-box-2" @scroll= "onScroll" ref= "box1" > < divclass = "top-item" v- for = "(item,index) in 6" : key= "index" > < / div> < / div> < ! -- 自定义滚动条 -- > < divclass = "bar" ref= "bar" > < ! -- 滚动滑块 -- > < spanref= "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" > < ! -- 滚动窗口 -- > < divclass = "top-box-2" @scroll= "onScroll" ref= "box1" > < divclass = "top-item" v- for = "(item,index) in 6" : key= "index" > < / div> < / div> < ! -- 自定义滚动条 -- > < divclass = "bar" ref= "bar" > < ! -- 滚动滑块 -- > < spanref= "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>