目录

1、缘起

2、实际示例

3、美化滚动条

4、Element-plus中的滚动条

5、关于实现方式的思考


1、缘起

之前在做项目时,发现一个项目中,各个子应用项目的UI表现不一致,看了下式Vue项目滚动条和其他的子应用项目表现明显不一致。

有时候为了使界面滚动条,各个浏览器的滚动条能保持一致,这样我们的项目避免在各个浏览器存在差异导致UI界面的不一致,这时候我们就可以考虑使用通用组件的方式,对各个需要滚动的页面,或者弹出窗口添加统一的组件进行包裹,来保证滚动效果在各个浏览器中能有更好的体验效果。

2、实际示例

我们以element-ui官网为例,看下默认滚动条实际效果。

在firefox 浏览器中,如下所示:

在Chrome 浏览器中,如下所示:

在Edge浏览器中,如下所示:

在以上各个浏览器中展示的效果来说,默认滚动条在各个浏览器中的表现都不一致,firefox浏览器和chrome浏览器相差就比较小,而与Edge浏览器相比相差就比较大了。

我们以element-ui官网为例,看下添加通用组件之后,滚动条实际效果。

在firefox 浏览器中,如下所示:

在chrome浏览器中,如下所示:

在Edge浏览器中,如下所示:

最后我们看到各个浏览器中滚动条的效果,基本上各个浏览器的表现效果是一致的,添加通用组件,默认情况下滚动条是不显示的,只有鼠标移动过去才会进行显示,整体上效果和用户体验会更好。

3、美化滚动条

我们打开这个网址(Create a New Pen (codepen.io))进行示例代码的编写。

我们对HTML 稍微改变以下,看下Dialog。

点击打开 Dialog这是一段信息这是一段信息这是一段信息这是一段信息这是一段信息这是一段信息这是一段信息这是一段信息取 消确 定.test {height: 100px;}.el-scrollbar__wrap{overflow-x: hidden;}

我们看下效果:

我们可以看到垂直滚动条的样式已经发生变化了,我们引用了element-ui的组件这个组件对超过高度的内容进行了包裹。

在element-ui(2.xx.xx)官网上,并没有找到有这个组件,实际上是有的,没有给出对应组件对应的文档,可能组件在设计的时候没有更好的完善吧。下载对应源码,看到是有这个组件的。

打开对应主文件,传递的属性有几个:

 props: {native: Boolean, // 是否使用原生方式wrapStyle: {},// 包裹容器的自定义样式wrapClass: {},// 包裹容器的自定义类名viewClass: {},// 视图的自定义样式viewStyle: {},// 视图的自定义类名noresize: Boolean, // 如果 container 尺寸不会发生变化,最好设置它可以优化性能tag: {// 视图的元素标签,默认为 div 标签type: String,default: 'div'}},

在源码顶部,看到有一个链接地址,是参考另一个插件的实现,如下所示

// reference https://github.com/noeldelgado/gemini-scrollbar/blob/master/index.js

打开它对应的网站(https://noeldelgado.github.io/gemini-scrollbar/),我们可以看到官网本身也进行了对应实现。

开发chrome开发工具,在元素标签页中,我们可以看到通过自定义节点,然后给节点添加对应的事件去进行实现的。

4、Element-plus中的滚动条

我们Element-plus 的官网,发现有滚动条组件对应的说明文档,如下所示:

通过文档给定的属性,发现和element-ui中的滚动条类型,只不过增加了宽、高等部分属性,使用起来和element-ui的滚动条没什么太大区别。

我们看一下如下示例:

{{ item }}

.scrollbar-demo-item {display: flex;align-items: center;justify-content: center;height: 50px;margin: 10px;text-align: center;border-radius: 4px;background: var(--el-color-primary-light-9);color: var(--el-color-primary);}

效果如下所示:

5、关于实现方式的思考

首先,我们检查滚动条的大小, 如果滚动条大小等于零(这意味着当前区域不需要滚动条) 那么我们什么都不做,否则我们“隐藏”本机滚动条(保留其功能 完整),并创建一对新的“滚动条”,由div组成,您可以完全自定义 用CSS这些“滚动条”将更新其位置,而 滚动以获得视觉反馈,如果您单击或拖动它们,也会做出响应。

例如,我们可以创建如下节点添加到html中。

.scrollbar-measure {width: 100px;height: 100px;overflow: scroll;position: absolute;top: -9999px;}

滚动条宽度,我们可以动态进行计算。

// Create the measurement nodevar scrollDiv = document.createElement("div");scrollDiv.className = "scrollbar-measure";document.body.appendChild(scrollDiv);// Get the scrollbar widthvar scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;console.warn(scrollbarWidth); // Mac:15// Delete the DIV document.body.removeChild(scrollDiv);

使用页面中的元素,从clientWidth中减去offsetWidth即可得到滚动条的大小! 最后一步是从DOM中删除DIV,完成了!

实际上很多其他组件的实现,基本上都是基于这样的方式去进行实现的。