首页 > 代码库 > 利用CSS3新特性实现完全兼容的自定义滚动条。
利用CSS3新特性实现完全兼容的自定义滚动条。
背景:最近项目里面因为统一页面风格,用到了自定义滚动条,在完成之前的那个滚动条的时候,与网上各个滚动条插件实现的方法类似,相当于造了轮子,通过css3的
网上看到的滚动条插件多数是通过监听内容的滚动事件,由于原生js的滚动事件存在一些bug,所以实际上用jQuery的mousewheel.js插件的比较多,自己做的滚动条也是引用了该插件。
首先说一说自定义滚动条实现的普遍步骤和方法:
背景: A需要滚动。
1.给A添加一个父级S包裹,并将B进行绝对或相对定位(这点根据S的定位,目的是为了保持原有布局)。
2.在S中生成A的兄弟节点B,B作为滚动条的容器,然后在B中生成滚动条bar,bar的高度通过容器S高度和A实际高度得出。
3.监听S的滚动事件,并在滚动事件中对A、bar进行top设置(横向滚动原理相同),这一点实现了自定义滚动条随内容滚动而位移。
4.监听滚动条bar的拖动事件,原理是监听bar的父级B的mouseDown和mouseUp事件,在鼠标按下的时候计算鼠标位移的距离,然后对应的修改A的top和bar的top。
以上就是普遍自定义滚动条的实现原理,在第3、4步中,需要设计算法保证正常的运行。
自己在写滚动条的时候,写到第4步就有了新的想法:省去第4步,滚动还是用浏览器自带的滚动条,样式自定义。这样做的好处有以下几点:
1.拥抱原生,减少代码,也减少了计算过程中容易导致的bug。
2.浏览器的滚动条功能已经完善,而自定义滚动条目的只是修改样式。
3.不必考虑兼容性。
上图为大致结构:A是内容部分,B是原生滚动条,C是自定义滚动条,C遮挡住B。
使用上面的步骤1、2、3我们可以实现滚动A时C随动的视觉效果,但是如何让C和B具有相同的功能,也就是如何让C控制A呢?还是看图
这是实现的效果图,这个想法能够实现得益于CSS3的新样式: pointer-events
pointer-events:auto | none | visiblepainted | visiblefill | visiblestroke | visible | painted | fill | stroke | all
默认值为auto,但是除了 auto 和 none,其它值只能用于svg上。
通过对C设置pointer-events:none样式后,C就可以不响应各种事件,并且不会阻止冒泡,相当于在用户眼睛蒙了一层C,用户实际操纵的是B,也就是使用的原生的滚动条。
我已经把滚动条封装在jQuery对象中,在使用的时候只需要引用该方法 $.lon_creatscroll(a,b,c) 并且指定内容部分和父级容器和滚动条颜色。
下面就是上图两个容器滚动条的实现代码。
源码中有更详细的实现步骤和注释,需要的可以访问 我的GitHub
利用CSS3新特性实现完全兼容的自定义滚动条。