用户经常使用鼠标在可滚动容器中滚动。除此之外,一些应用程序还允许用户通过拖动元素来滚动。
这篇文章向您展示了一种使用 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')
}

 京公网安备 11010502036488号
京公网安备 11010502036488号