js
class Scroller {
constructor() {
this.parent = document.querySelector('.parent')
this.child = document.querySelector('.child')
this.scroller = document.querySelector('.scroller')
this.slider = document.querySelector('.slider')
this.listen()
this.setSliderWidth()
}
listen = () => {
this.parent.onscroll = this.onScroll
this.scroller.onclick = this.onClickScroller
this.slider.onmousedown = this.onDrag
}
setSliderWidth = () => {
let percent = 100
const maxWidth = this.parent.clientWidth
let width = this.child.scrollWidth
percent = Math.min(maxWidth / width * 100, 100)
const newWidth = `${percent.toFixed(3)}%`
const sliderStyle = this.slider.style
if (newWidth !== sliderStyle.width) {
sliderStyle.width = newWidth
}
}
onScroll = e => {
const maxWidth = this.scroller.clientWidth
const sliderWidth = this.slider.clientWidth
const { scrollLeft, scrollWidth, clientWidth } = this.parent
const percent = scrollLeft / (scrollWidth - clientWidth)
this.slider.style.left = `${(maxWidth - sliderWidth) * percent}px`
}
onClickScroller = e => {
if (this.startX) return
const { left, width } = this.scroller.getBoundingClientRect()
const scrollWidth = this.parent.scrollWidth
const percent = (e.pageX - left) / width
this.parent.scrollLeft = percent * scrollWidth
}
onDrag = (e) => {
this.startX = e.pageX - this.slider.offsetLeft
document.addEventListener('mousemove', this.onMouseMove)
document.addEventListener('mouseup', this.onMouseUp)
}
onMouseMove = (e) => {
const maxWidth = this.scroller.clientWidth
const sliderWidth = this.slider.clientWidth
const left = e.pageX - this.startX
const body = this.parent
const rate = left / (maxWidth - sliderWidth)
body.scrollLeft = rate * (body.scrollWidth - body.clientWidth)
}
onMouseUp = (e) => {
setTimeout(() => this.startX = null)
document.removeEventListener('mousemove', this.onMouseMove)
document.removeEventListener('mouseup', this.onMouseUp)
}
}
new Scroller()
dom
<div class="box">
<div class="parent">
<div class="child">0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899</div>
</div>
<div class="scroller">
<div class="slider"></div>
</div>
</div>
style
div::-webkit-scrollbar {
display: none;
}
.box {
position: fixed;
left: 0; right: 0; top: 0; bottom: 0; margin: auto;
width: 200px;
height: 200px;
}
.parent {
width: 100%; height: 100%;
background: #333;
overflow: scroll;
border-radius: 4px;
}
.child {
margin-top: 10px;
background: #ddd;
width: max-content;
}
.scroller {
width: 100%;
height: 8px;
background: #e4e4e4;
position: absolute;
bottom: 0;
border-radius: 4px;
cursor: default;
transition: all .4s;
}
.slider {
height: 100%;
background: #c5c5c5;
border-radius: 4px;
position: relative;
cursor: default;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具