1 回答
TA贡献1841条经验 获得超3个赞
首先:可以仅使用 HTML 和 CSS 构建滚动条,但需要使用 Javascript。
简单的滚动条
您可以使用 position
、border
和 border-radius
实现此外观。轨道获取左侧和右侧的边框,拇指通过 border-radius: 50%
获取所有侧面的边框,另外还有一个白色遮罩(轨道的宽度减去其边框)用于隐藏轨道轨道内的拇指边框。当然你还需要红点。所有五个元素都会得到 position: absolute
。
<div id="scrollbar">
<div id="track"></div>
<div id="thumb">
<div class="white_mask"></div>
<div id="red_dot"></div>
</div>
</div>
基本 CSS(无尺寸)
#scrollbar {
position: absolute;
}
#track {
position: absolute;
border-right: 3px solid #000;
border-left: 3px solid #000;
}
#thumb {
position: absolute;
border: 1px solid #000;
border-radius: 50%;
background-color: white;
}
.white_mask {
position: absolute;
background-color: white;
}
#red_dot {
position: absolute;
border-radius: 50%;
background-color: #9c0000;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#container {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
#scrollbar {
position: absolute;
right: 100px;
top: 0;
width: 120px;
height: 100%;
z-index: 10;
}
#track {
position: absolute;
top: 0;
right: 20px;
width: 80px;
height: 100%;
border-right: 12px solid #000;
border-left: 12px solid #000;
}
#thumb {
position: absolute;
top: 0;
right: 0;
width: 120px;
height: 128px;
border: 4px solid #000;
border-top: 8px solid #000;
border-bottom: 8px solid #000;
border-radius: 50%;
background-color: white;
}
.white_mask {
position: absolute;
top: -8px;
right: 28px;
width: 56px;
height: 128px;
background-color: white;
}
.white_mask.big {
top: -16px;
right: 12px;
width: 88px;
height: 144px;
}
#thumb_mask {
position: absolute;
top: -16px;
left: 8px;
width: 96px;
height: 144px;
overflow: hidden;
}
.quarter_border {
position: absolute;
width: 80px;
height: 100px;
border-right: 12px solid #000;
border-left: 12px solid #000;
border-radius: 50%;
background-color: white;
}
.quarter_border.top {
top: -52px;
}
.quarter_border.right {
right: -60px;
}
.quarter_border.bottom {
bottom: -52px;
}
.quarter_border.left {
left: -60px;
}
#red_dot {
position: absolute;
top: 0;
left: 0;
width: 112px;
height: 112px;
border: 8px solid white;
border-radius: 50%;
background-color: #9c0000;
}
<div id="container">
<div id="scrollbar">
<div id="track"></div>
<div id="thumb">
<div class="white_mask"></div>
<div id="red_dot"></div>
</div>
</div>
</div>
高级滚动条
由于拇指和轨道相互交汇处存在小角,因此您可以使用 overflow: hidden 在遮罩 div 中添加四个具有圆形边框的附加 div,这样四个 div 中的四分之一即可可见的。您还需要在四个 div 下使用第二个白色蒙版来隐藏角落。
要增加和减少border-width,您需要为上/下边框和左/右边框定义不同的值。此外,红点需要一个白色边框来平滑拇指边框的内部。
<div id="scrollbar">
<div id="track"></div>
<div id="thumb">
<div class="white_mask"></div>
<div class="white_mask small"></div>
<div id="thumb_mask">
<div class="quarter_border top right"></div>
<div class="quarter_border bottom right"></div>
<div class="quarter_border top left"></div>
<div class="quarter_border bottom left"></div>
</div>
<div id="red_dot"></div>
</div>
</div>
附加 CSS(无尺寸)
#thumb {
...
border-top: 2px solid #000;
border-bottom: 2px solid #000;
}
#thumb_mask {
position: absolute;
overflow: hidden;
}
.quarter_border {
position: absolute;
border-right: 3px solid #000;
border-left: 3px solid #000;
border-radius: 50%;
background-color: white;
}
#red_dot{
...
border: 2px solid white;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#container {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
#scrollbar {
position: absolute;
right: 100px;
top: 0;
width: 120px;
height: 100%;
z-index: 10;
}
#track {
position: absolute;
top: 0;
right: 20px;
width: 80px;
height: 100%;
border-right: 12px solid #000;
border-left: 12px solid #000;
}
#thumb {
position: absolute;
top: 0;
right: 0;
width: 120px;
height: 128px;
border: 4px solid #000;
border-top: 8px solid #000;
border-bottom: 8px solid #000;
border-radius: 50%;
background-color: white;
}
.white_mask {
position: absolute;
top: -4px;
right: 28px;
width: 56px;
height: 128px;
background-color: white;
}
.white_mask.big {
top: -16px;
right: 12px;
width: 88px;
height: 144px;
}
#thumb_mask {
position: absolute;
top: -16px;
left: 8px;
width: 96px;
height: 144px;
overflow: hidden;
}
.quarter_border {
position: absolute;
width: 80px;
height: 100px;
border-right: 12px solid #000;
border-left: 12px solid #000;
border-radius: 50%;
background-color: white;
}
.quarter_border.top {
top: -52px;
}
.quarter_border.right {
right: -60px;
}
.quarter_border.bottom {
bottom: -52px;
}
.quarter_border.left {
left: -60px;
}
#red_dot {
position: absolute;
top: 0;
left: 0;
width: 112px;
height: 112px;
border: 8px solid white;
border-radius: 50%;
background-color: #9c0000;
}
<div id="container">
<div id="scrollbar">
<div id="track"></div>
<div id="thumb">
<div class="white_mask"></div>
<div class="white_mask big"></div>
<div id="thumb_mask">
<div class="quarter_border top right"></div>
<div class="quarter_border bottom right"></div>
<div class="quarter_border top left"></div>
<div class="quarter_border bottom left"></div>
</div>
<div id="red_dot"></div>
</div>
</div>
</div>
不幸的是,这些硬币并不完全适合拇指和轨道。因此,将滚动条构建为 SVG 并操作其组件可能是更好的方法。
基础 JavaScript
有多种可能性和功能可以通过不同的属性来操作滚动条,例如top、scrollTop 或transform。我在这里仅用于演示top和一些基本功能(例如我省略了resize上滚动位置的调整)。
基本常数
为了让滚动条首先工作,您需要三个常量thumb_height(包括其边框)、scroll_range(最大拇指位置)和 diff_height(隐藏内容)。
const thumb_height = thumb.getBoundingClientRect().height;
const scroll_range = window.innerHeight - thumb_height;
const diff_height = content.scrollHeight - window.innerHeight
滚动功能
然后,您需要滚动函数,在其中计算新的拇指位置和内容滚动,并设置两个元素的样式(如果拇指位于滚动范围内)。
内容滚动是初始隐藏内容的可见百分比。百分比的计算方式为:拇指位置除以其最大值(滚动范围)。
拖动拇指:
您可以从 mousedown 事件中的鼠标光标位置获取拇指位置:e.clientY(按拇指高度的一半进行校正)。
您还必须确保当拇指位置变得太小或太大时,例如离开容器(此处为窗口)时,拇指不会消失。因此,您必须检查位置是否低于 0 或高于滚动范围,只有在没有的情况下才对元素设置样式。
function dragThumb(e) {
const thumb_pos = e.clientY - (thumb_height / 2);
const content_scroll = -diff_height * thumb_pos / scroll_range;
if (thumb_pos >= 0 && thumb_pos <= scroll_range) {
thumb.style.top = thumb_pos + 'px';
content.style.top = content_scroll + 'px';
}
}
对于鼠标滚轮:
您可以从拇指增加或减少的实际 top 属性获取拇指位置(取决于 wheel 事件中的鼠标滚轮方向:e.deltaY)固定量100(您可以修改该值以更快或更慢地滚动)。
对于样式,您还必须处理两种极端条件,因为重击位置(以固定量计算)有时不会“落地”。正好在 0 或滚动范围上。您可以使用 if 块来完成此操作,如 dragThumb() (您需要 3 个),或者您可以使用三元运算符 ? :,如以下代码片段。
function scrollContent(e) {
const thumb_pos = parseInt(thumb.style.top) + (e.deltaY < 0 ? -100 : 100);
const content_scroll = -diff_height * thumb_pos / scroll_range;
thumb.style.top = thumb_pos < 0 ? 0 : (thumb_pos > scroll_range ? scroll_range : thumb_pos) + 'px';
content.style.top = thumb_pos < 0 ? 0 : (thumb_pos > scroll_range ? -diff_height : content_scroll) + 'px';
}
事件监听器
最后,您需要一个事件监听器,您可以在其中调用滚动函数。
对于鼠标滚轮:
document.addEventListener('wheel', scrollContent);
拖动拇指:
您需要两个额外的事件侦听器,一个仅在最初单击拇指时侦听鼠标移动,另一个用于在释放鼠标按钮时删除该鼠标移动侦听器。
thumb.addEventListener('mousedown', function(e) {
e.preventDefault(); // fixed a bug with 'mouseup'
document.addEventListener('mousemove', dragThumb);
});
document.addEventListener('mouseup', function() {
document.removeEventListener('mousemove', dragThumb);
});
工作示例:
两个滚动函数都合并到函数scrollContent()中。拇指位置是在两个事件处理程序(调用 scrollContent())中计算的:dragThumb() 和 wheel 事件的匿名函数。
这三个常量是在页面加载和窗口调整大小时调用的重置函数resetScroll()(因此定义为普通变量let)中计算的。该函数还使用实际的拇指位置调用滚动函数scrollContent()。
因为 mouseup 的事件侦听器“聋”如果事件发生在堆栈片段之外,我将其匿名函数转换为函数 stopDrag() ,该函数被称为 mouseup 和 mouseleave
document.addEventListener('DOMContentLoaded', function() {
const thumb = document.getElementById('thumb');
const content = document.getElementById('content');
let thumb_height, scroll_range, diff_height;
function resetScroll() {
thumb_height = thumb.getBoundingClientRect().height;
scroll_range = window.innerHeight - thumb_height;
diff_height = content.scrollHeight - window.innerHeight;
scrollContent(parseInt(thumb.style.top));
}
function scrollContent(thumbPos) {
const newScroll = -diff_height * thumbPos / scroll_range;
thumb.style.top = thumbPos < 0 ? 0 : (thumbPos > scroll_range ? scroll_range : thumbPos) + 'px';
content.style.top = thumbPos < 0 ? 0 : (thumbPos > scroll_range ? -diff_height : newScroll) + 'px';
}
function dragThumb(e) {
scrollContent(e.clientY - (thumb_height / 2));
}
function stopDrag(e) {
document.removeEventListener('mousemove', dragThumb);
}
thumb.addEventListener('mousedown', function(e) {
e.preventDefault();
document.addEventListener('mousemove', dragThumb);
});
document.addEventListener('mouseup', stopDrag);
document.addEventListener("mouseleave", stopDrag);
document.addEventListener('wheel', function(e) {
if (!e.ctrlKey) {
scrollContent(parseInt(thumb.style.top) + (e.deltaY < 0 ? -100 : 100));
}
});
window.addEventListener('resize', resetScroll);
//initial reset
document.scrollTop = 0;
thumb.style.top = 0;
resetScroll();
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#container {
position: relative;
overflow: hidden;
}
#content {
position: relative;
top: 0;
right: 0;
width: 100vw;
height: 100vh;
padding-right: 40px;
}
#scrollbar {
position: absolute;
right: 5px;
top: 0;
width: 30px;
height: 100%;
z-index: 10;
}
#track {
position: absolute;
top: 0;
right: 5px;
width: 20px;
height: 100%;
border-right: 3px solid #000;
border-left: 3px solid #000;
}
#thumb {
position: absolute;
top: 0;
right: 0;
width: 30px;
height: 32px;
border: 1px solid #000;
border-top: 2px solid #000;
border-bottom: 2px solid #000;
border-radius: 50%;
background-color: white;
}
.white_mask {
position: absolute;
top: -3px;
right: 6px;
width: 14px;
height: 30px;
background-color: white;
}
.white_mask.big {
top: -4px;
right: 3px;
width: 22px;
height: 36px;
}
#thumb_mask {
position: absolute;
top: -4px;
left: 2px;
width: 24px;
height: 36px;
overflow: hidden;
}
.quarter_border {
position: absolute;
width: 20px;
height: 25px;
border-right: 3px solid #000;
border-left: 3px solid #000;
border-radius: 50%;
background-color: white;
}
.quarter_border.top {
top: -13px;
}
.quarter_border.right {
right: -15px;
}
.quarter_border.bottom {
bottom: -13px;
}
.quarter_border.left {
left: -15px;
}
#red_dot {
position: absolute;
top: 0;
left: 0;
width: 28px;
height: 28px;
border: 2px solid white;
border-radius: 50%;
background-color: #9c0000;
}
<div id="container">
<div id="scrollbar">
<div id="track"></div>
<div id="thumb">
<div class="white_mask"></div>
<div class="white_mask big"></div>
<div id="thumb_mask">
<div class="quarter_border top right"></div>
<div class="quarter_border bottom right"></div>
<div class="quarter_border top left"></div>
<div class="quarter_border bottom left"></div>
</div>
<div id="red_dot"></div>
</div>
</div>
<div id="content">
<p>first</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>last</p>
</div>
</div>
- 1 回答
- 0 关注
- 86 浏览
添加回答
举报