记录--让整个网站界面无滚动条
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
界面无滚动条
滚动条的优化也有很多种,比如随便再网上搜索美化浏览器滚动条样式
,就会出现些用css
去美化滚动条的方案。
那种更好呢?
没有更好只有更合适
- 像默认的滚动条的话,他能让你方便摁着往下滑动(他比较宽)特别省劲,不用担心美化过后变细摁不到问题。
- 美化后的滚动条样式啊更贴合网站主题,让用户体验更好。
- 无滚动条(鼠标放上去后出现)这种更适合像一个页面好多个块,每个块的话还很多内容(都有滚动条)。如果像这种都默认都出现滚动条的话,也太不美观了。
那咱们就从无滚动条展开说说!!!
无滚动条设计
比如像
element ui
组件内像input
的自定义模块数据过多的时候出现的下拉框内的滚动条,如下图:
在element-ui
里面它其实是有内部组件el-scrollbar在的。那么它是怎么实现无滚动条呢?
如下图咱们先把:hover
勾选上让滚动条一直处于显示得状态。然后咱们再分析他的实现。
当我把样式稍微修改下,咱们再观察下图:
这么看是不是就很明白了 他其实用margin
值把整个容器扩大了点然后溢出隐藏,其实滚动条还在就是给界面上看不到了而已。
然后它自己用dom
画了个滚动条,如下图:
经过上面分析,咱们已经很清楚得了解到一个无滚动条是从那个方面实现得了。
- 使用
margin
值把滚动条给溢出隐藏掉。- 使用
div
自己画了一个滚动条。方便咱们隐藏、显示、更改样式等。
无滚动条实现
那咱们再从细节上拆分下具体实现要考虑那些点:
- 需要计算滚动条得宽度用来
margin
扩大得距离(每个界面上得滚动条得宽度是不一样得)。 - 需要计算画的
div
滚动条得高度(这个内容多少会影响滚动条的高度)。 - 需要根据滚动条去
transform: translateY(19.3916%);
移动咱们自己画的div
滚动条的。 - 需要根据摁着画的
div
滚动条,去实际更改需要滚动的高度。 - 需要点击滚动轴的柱子支持跳到目标的滚动位置;
一 计算界面原本滚动条的宽度
计算下界面上原本滚动条的宽度如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | let scrollBarWidth; export default function() { if (scrollBarWidth !== undefined) return scrollBarWidth; const outer = document.createElement( 'div' ); outer.className = 'el-scrollbar__wrap' ; outer.style.visibility = 'hidden' ; outer.style.width = '100px' ; outer.style.position = 'absolute' ; outer.style.top = '-9999px' ; document.body.appendChild(outer); const widthNoScroll = outer.offsetWidth; outer.style.overflow = 'scroll' ; const inner = document.createElement( 'div' ); inner.style.width = '100%' ; outer.appendChild(inner); const widthWithScroll = inner.offsetWidth; outer.parentNode.removeChild(outer); scrollBarWidth = widthNoScroll - widthWithScroll; return scrollBarWidth; }; |
先创建了一个
div
, 设置成scroll
, 然后再在里面嵌套一个没有滚动条的div
设置宽度100%
, 获取到两者的offsetWidth
, 相减获取到scrollBarWidth
。赋值给scrollBarWidth
是惰性加载的优化,只需要计算一次就可以了。 具体展现如下图:
二 计算画的滚动条的高度height
计算下画的
div
滚动条的高度height
。是用当前容器的内部高度 / 容器整个滚动条的高度 * 100计算出百分比;
比如:
1 2 3 | const warp = this .$refs.wrap; // 或者使用documnet获取容器 const heightPercentage = (wrap.clientHeight * 100 / wrap.scrollHeight); // height const widthPercentage = (wrap.clientWidth * 100 / wrap.scrollWidth); // width |
解析: 如当前容器高
30px
,内容撑起来总共高100px
,那么滚动条的高度就是当前容器的30%
;
三 计算滚动条需要移动的值
计算画的
div
需要滚动条的高度moveY
是, 获取当前容器滚动的scrollTop
/ 当前容器内部高度 * 100:
算法一:
解析 使用
transform: translateY(0%);
是移动的是自己本身的百分比那么(容器滚动的scrollTop
/ 当前容器内部高度 * 100)算法如下:
1 2 3 | const warp = this .$refs.wrap; // 或者使用documnet获取容器 this .moveY = ((wrap.scrollTop * 100) / wrap.clientHeight); this .moveX = ((wrap.scrollLeft * 100) / wrap.clientWidth); |
算法二:
解析:使用定位
top
值,这个比较好理解滚动条的滚动 / 容器的滚动总高度 * 100得到百分比,如下:
1 2 3 | const warp = this .$refs.wrap; // 或者使用documnet获取容器 this .moveY = ((wrap.scrollTop * 100) / wrap.scrollHeight); this .moveX = ((wrap.scrollLeft * 100) / wrap.scrollWidth); |
把计算出来的
moveY
、moveX
的方法 绑定给scroll
滚动事件就可以了。
四 摁着画的div
滚动条 经行拖动
滚动条都是支持拖着上下左右移动的,那咱们也要支持下:
- 获取当前滚动条的高度或者宽度可以使用
getBoundingClientRect()
如下图: - 获取拖着移动的距离 就是再鼠标摁下先计一个当前的
x1、y1
监听move
的x2、y2
相减就是拖动的距离了。 - 获取到拖动的距离后转成
transform || top
值。
一个简单的拖动组件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | <template> <div ref = "draggableRef" class = "draggable" :style= "style" > <slot /> </div> </template> <script> export default { name: 'DraggableComponent' , props: { initialValue: { type: Object, required: false , default : () => ({ x: 0, y: 0 }), }, }, data() { return { currentValue: { x: 0, y: 0 }, isDragging: false , startX: 0, startY: 0, diffX: 0, diffY: 0, }; }, computed: { style() { return `left: ${ this .currentValue.x + this .diffX}px; top: ${ this .currentValue.y + this .diffY}px`; }, }, watch: { initialValue: { handler(val) { this .currentValue = val; }, immediate: true , }, }, mounted() { this .$nextTick(() => { const { draggableRef } = this .$refs; if (draggableRef) { draggableRef.addEventListener( 'mousedown' , this .startDrag); document.addEventListener( 'mousemove' , this .moveDrag); document.addEventListener( 'mouseup' , this .endDrag); } }); }, beforeDestroy() { const { draggableRef } = this .$refs; draggableRef.removeEventListener( 'mousedown' , this .startDrag); document.removeEventListener( 'mousemove' , this .moveDrag); document.removeEventListener( 'mouseup' , this .endDrag); }, methods: { startDrag({ clientX: x1, clientY: y1 }) { this .isDragging = true ; document.onselectstart = () => false ; this .startX = x1; this .startY = y1; }, moveDrag({ clientX: x2, clientY: y2 }) { if ( this .isDragging) { this .diffX = x2 - this .startX; this .diffY = y2 - this .startY; } }, endDrag() { this .isDragging = false ; document.onselectstart = () => true ; this .currentValue.x += this .diffX; this .currentValue.y += this .diffY; this .diffX = 0; this .diffY = 0; }, }, }; </script> <style> .draggable { position: fixed ; z-index: 9; } </style> |
咱们需要获取到画的滚动条的高度,然后根据拖动的距离算出来
transform: translateY(0%);
或者top
值;
如上面拖动组件 拖动部分代码就不在重复了 咱们直接用diffX、diffY、lastX、lastY
来用了。
diffX、diffY
是拖动差的值lastX、lastY
是上一次也就是未拖动前的值translateY || top
算法一(transform)
1 2 3 4 5 6 7 | const thumb = document.querySelector( 'el-scrollbar__thumb' ); // element ui el-scrollbar 的滚动条 const { height: thumbHeight } = thumb?.getBoundingClientRect() || {}; const diffY = 10; const lastY = '300' ; // transform: translateY(300%);` const moveY = (diffY / thumbHeight) + lastY; |
1 2 3 4 5 6 7 | const thumb = document.querySelector( 'el-scrollbar__thumb' ); // element ui el-scrollbar 的滚动条 const { height: thumbHeight } = thumb?.getBoundingClientRect() || {}; const diffY = 10; const lastY = 30; // top: 30%` const moveY = (diffY / wrap.scrollWidth * 100) + lastY; |
五 点击滚动轴使滚动条跳转到该位置
- getBoundingClientRect 的 top 是获取到距离浏览器顶部的距离。 写一个点击事件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function clickTrackHandler( event ) { const wrap = this .$refs.wrap; // 1. 减去clientX 正好能获取到需要滚动到的位置 const offset = Math.abs(e.target.getBoundingClientRect().top - e.clientX); // 2. 利用offset 的到画的滚动条的实际位置 两种算法transform || top const thumb = document.querySelector( 'el-scrollbar__thumb' ); // element ui el-scrollbar 的滚动条 const { height: thumbHeight } = thumb?.getBoundingClientRect() || {}; const translateY = offset / height * 100; // transform const top = offset / wrap.scrollHeight * 100; // top // 3、计算实际需要滚动的高度 使界面滚动到该位置。两种算法transform(scrollTop2) || top(scrollTop1) const scrollTop1 = top * wrap.scrollHeight; // top const scrollTop2 = translateY * wrap.clientHeight; // transform } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2022-06-30 记录--Event Loop事件循环、微任务、宏任务