用户经常使用鼠标在可滚动容器中滚动。除此之外,一些应用程序还允许用户通过拖动元素来滚动。
这篇文章向您展示了一种使用 vanilla JavaScript 实现该功能的简单方法。
假设我们有一个可滚动的容器,如下所示:
<div id="container" class="container">...</div>
元素必须至少有两个 CSS 属性:
.container {
cursor: grab;
overflow: auto;
}
cursor: grab
表示该元素可以点击和拖动。
只要元素是可滚动的,我们就可以通过设置 scrollTop
或 scrollLeft
属性将其滚动到给定位置:
const ele = document.getElementById('container')
ele.scrollTop = 100
ele.scrollLeft = 150
实现非常简单。通过使用 mousedown
用户单击元素时发生的事件:
let pos = {
top: 0,
left: 0,
x: 0,
y: 0
}
const mouseDownHandler = function (e) {
pos = {
// 当前滚动
left: ele.scrollLeft,
top: ele.scrollTop,
// 获取当前鼠标位置
x: e.clientX,
y: e.clientY
}
document.addEventListener('mousemove', mouseMoveHandler)
document.addEventListener('mouseup', mouseUpHandler)
}
pos
存储当前的滚动和鼠标位置。当用户移动鼠标时,我们计算它移动了多远,然后滚动到元素到相同的位置:
const mouseMoveHandler = function (e) {
// 鼠标移动了多远
const dx = e.clientX - pos.x
const dy = e.clientY - pos.y
// 滚动元素
ele.scrollTop = pos.top - dy
ele.scrollLeft = pos.left - dx
}
正如你看到的上面的 left
、top
、x
和 y
属性是相互关联的。最好将它们封装在单个变量中,pos
而不是创建四个变量。
最后,我们可以通过在用户开始移动鼠标时设置一些 CSS 属性来改善用户体验:
const mouseDownHandler = function (e) {
// 改变光标并阻止用户选择文本
ele.style.cursor = 'grabbing'
ele.style.userSelect = 'none'
// ...
}
释放鼠标时,移除事件并重置这些 CSS 属性:
const mouseUpHandler = function () {
document.removeEventListener('mousemove', mouseMoveHandler)
document.removeEventListener('mouseup', mouseUpHandler)
ele.style.cursor = 'grab'
ele.style.removeProperty('user-select')
}