下面我给你详细讲解“原生js封装自定义滚动条”的完整攻略。
步骤1:创建HTML结构
首先我们需要创建一个包含内容的元素和一个自定义滚动条的容器。
<div class="scroll-wrapper">
<div class="scroll-content">
<!-- 包含内容的元素 -->
</div>
<div class="scroll-track">
<div class="scroll-bar"></div>
</div>
</div>
其中,.scroll-wrapper
是我们的自定义滚动条容器,.scroll-content
是包含内容的元素,.scroll-track
是滚动条轨道,.scroll-bar
是滚动条。
步骤2:CSS样式
接下来我们需要设置各个元素的CSS样式。具体的样式可以根据自己的需要来调整,这里只展示一个基本的样式。
.scroll-wrapper {
position: relative;
overflow: hidden;
}
.scroll-content {
width: 100%;
height: 100%;
overflow-y: scroll;
padding-right: 16px; /* 减去滚动条的宽度 */
}
.scroll-track {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 10px; /* 滚动条的宽度 */
}
.scroll-bar {
position: absolute;
top: 0;
width: 10px; /* 滚动条的宽度 */
cursor: pointer;
background-color: #ccc;
border-radius: 5px;
}
步骤3:JS封装
使用原生JS封装自定义滚动条,大致的思路如下:
- 获取相关元素,包括内容元素、滚动条元素、滚动条轨道元素
- 计算滚动条的高度和位置
- 给滚动条绑定拖动事件,实现拖动滚动条滚动内容的效果
- 给内容元素绑定滚动事件,实现滚动内容时同时移动滚动条的效果
下面就是基本的JS代码:
function Scrollbar(container) {
var content = container.querySelector('.scroll-content');
var track = container.querySelector('.scroll-track');
var bar = container.querySelector('.scroll-bar');
var contentHeight = content.scrollHeight;
var containerHeight = content.clientHeight;
var trackHeight = track.clientHeight;
var maxScrollTop = contentHeight - containerHeight;
bar.style.height = (containerHeight / contentHeight) * trackHeight + 'px';
var scrollRatio = maxScrollTop / (trackHeight - bar.clientHeight);
bar.addEventListener('mousedown', function(e) {
e.preventDefault();
var startY = e.clientY;
var startTop = parseInt(getComputedStyle(bar).top);
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', stopDrag);
function drag(e) {
var deltaY = e.clientY - startY;
var newTop = startTop + deltaY;
if (newTop < 0) {
newTop = 0;
}
if (newTop + bar.clientHeight > trackHeight) {
newTop = trackHeight - bar.clientHeight;
}
bar.style.top = newTop + 'px';
content.scrollTop = newTop * scrollRatio;
}
function stopDrag() {
document.removeEventListener('mousemove', drag);
document.removeEventListener('mouseup', stopDrag);
}
});
content.addEventListener('scroll', function() {
bar.style.top = (content.scrollTop / scrollRatio) + 'px';
});
}
var container = document.querySelector('.scroll-wrapper');
var scrollbar = new Scrollbar(container);
上述代码中,我们先获取了各个DOM元素,然后计算了滚动条的高度和滚动比例。接着给滚动条绑定了拖动事件,并且实现了拖动滚动条滚动内容的功能。最后给内容元素绑定了滚动事件,实现了滚动内容时同时移动滚动条的功能。
示例1:水平滚动条
如果需要创建一个水平滚动条的话,只需要修改一些CSS样式和JS代码即可。
首先是HTML结构:
<div class="scroll-wrapper horizontal">
<div class="scroll-content">
<!-- 包含内容的元素 -->
</div>
<div class="scroll-track">
<div class="scroll-bar"></div>
</div>
</div>
然后是CSS样式:
.scroll-wrapper.horizontal {
overflow-x: scroll;
}
.scroll-wrapper.horizontal .scroll-content {
white-space: nowrap;
padding-bottom: 16px; /* 减去滚动条的高度 */
padding-right: 0;
}
.scroll-wrapper.horizontal .scroll-track {
height: 10px; /* 滚动条的高度 */
}
.scroll-wrapper.horizontal .scroll-bar {
height: 10px; /* 滚动条的高度 */
width: 100px;
}
最后是JS代码:
function Scrollbar(container) {
var content = container.querySelector('.scroll-content');
var track = container.querySelector('.scroll-track');
var bar = container.querySelector('.scroll-bar');
var contentWidth = content.scrollWidth;
var containerWidth = content.clientWidth;
var trackWidth = track.clientWidth;
var maxScrollLeft = contentWidth - containerWidth;
bar.style.width = (containerWidth / contentWidth) * trackWidth + 'px';
var scrollRatio = maxScrollLeft / (trackWidth - bar.clientWidth);
bar.addEventListener('mousedown', function(e) {
e.preventDefault();
var startX = e.clientX;
var startLeft = parseInt(getComputedStyle(bar).left);
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', stopDrag);
function drag(e) {
var deltaX = e.clientX - startX;
var newLeft = startLeft + deltaX;
if (newLeft < 0) {
newLeft = 0;
}
if (newLeft + bar.clientWidth > trackWidth) {
newLeft = trackWidth - bar.clientWidth;
}
bar.style.left = newLeft + 'px';
content.scrollLeft = newLeft * scrollRatio;
}
function stopDrag() {
document.removeEventListener('mousemove', drag);
document.removeEventListener('mouseup', stopDrag);
}
});
content.addEventListener('scroll', function() {
bar.style.left = (content.scrollLeft / scrollRatio) + 'px';
});
}
var container = document.querySelector('.scroll-wrapper.horizontal');
var scrollbar = new Scrollbar(container);
示例2:带缓动效果的滚动条
如果需要让滚动条滚动的过程更加流畅,可以加上缓动效果。
首先是修改JS代码中的拖动事件:
function drag(e) {
var deltaY = e.clientY - startY;
var newTop = startTop + deltaY;
if (newTop < 0) {
newTop = 0;
}
if (newTop + bar.clientHeight > trackHeight) {
newTop = trackHeight - bar.clientHeight;
}
var scrollTop = newTop * scrollRatio;
animatedScroll(content, scrollTop);
}
function animatedScroll(element, scrollTop) {
var start = element.scrollTop;
var end = scrollTop;
var startTime = performance.now();
var duration = 500; // 滚动持续500ms
requestAnimationFrame(function scroll(time) {
var elapsed = time - startTime;
if (elapsed < duration) {
var position = easeInOutQuad(elapsed, start, end - start, duration);
element.scrollTop = position;
requestAnimationFrame(scroll);
} else {
element.scrollTop = end;
}
});
}
function easeInOutQuad(t, b, c, d) {
t = t / (d / 2);
if (t < 1) {
return c / 2 * t * t + b;
} else {
t = t - 1;
return -c / 2 * (t * (t - 2) - 1) + b;
}
}
这里使用了requestAnimationFrame()
和performance.now()
方法实现缓动效果。然后需要加上一个缓动函数easeInOutQuad()
,这个函数可以根据需要修改,这里是一个缓慢开始,缓慢结束的二次函数。
最后是示例代码:
<div class="scroll-wrapper easing">
<div class="scroll-content">
<!-- 包含内容的元素 -->
</div>
<div class="scroll-track">
<div class="scroll-bar"></div>
</div>
</div>
.scroll-wrapper.easing .scroll-bar {
transition: top 0.5s ease-out;
}
.scroll-wrapper.easing .scroll-content {
scroll-behavior: smooth;
}
function Scrollbar(container) {
var content = container.querySelector('.scroll-content');
var track = container.querySelector('.scroll-track');
var bar = container.querySelector('.scroll-bar');
var contentHeight = content.scrollHeight;
var containerHeight = content.clientHeight;
var trackHeight = track.clientHeight;
var maxScrollTop = contentHeight - containerHeight;
bar.style.height = (containerHeight / contentHeight) * trackHeight + 'px';
var scrollRatio = maxScrollTop / (trackHeight - bar.clientHeight);
bar.addEventListener('mousedown', function(e) {
e.preventDefault();
var startY = e.clientY;
var startTop = parseInt(getComputedStyle(bar).top);
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', stopDrag);
function drag(e) {
var deltaY = e.clientY - startY;
var newTop = startTop + deltaY;
if (newTop < 0) {
newTop = 0;
}
if (newTop + bar.clientHeight > trackHeight) {
newTop = trackHeight - bar.clientHeight;
}
var scrollTop = newTop * scrollRatio;
animatedScroll(content, scrollTop);
bar.style.top = newTop + 'px';
}
function stopDrag() {
document.removeEventListener('mousemove', drag);
document.removeEventListener('mouseup', stopDrag);
}
});
content.addEventListener('scroll', function() {
bar.style.top = (content.scrollTop / scrollRatio) + 'px';
});
}
function animatedScroll(element, scrollTop) {
var start = element.scrollTop;
var end = scrollTop;
var startTime = performance.now();
var duration = 500; // 滚动持续500ms
// 动画函数
requestAnimationFrame(function scroll(time) {
var elapsed = time - startTime;
if (elapsed < duration) {
var position = easeInOutQuad(elapsed, start, end - start, duration);
element.scrollTop = position;
requestAnimationFrame(scroll);
} else {
element.scrollTop = end;
}
});
}
function easeInOutQuad(t, b, c, d) {
t = t / (d / 2);
if (t < 1) {
return c / 2 * t * t + b;
} else {
t = t - 1;
return -c / 2 * (t * (t - 2) - 1) + b;
}
}
var container = document.querySelector('.scroll-wrapper.easing');
var scrollbar = new Scrollbar(container);
以上就是“原生js封装自定义滚动条”的详细攻略,希望能对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:原生js封装自定义滚动条 - Python技术站