假设我们要将以下元素变成可拖动元素:

<div id="dragMe" class="draggable">Drag me</div>

该元素需要具有以下样式:

.draggable {
  /* 指示元素可拖动 */
  cursor: move;

  /* 绝对定位 */
  position: absolute;

  /* 不允许选择里面的内容 */
  user-select: none;
}

为了使其可拖动,我们需要处理三个事件:

  • mousedown(在元素上):跟踪鼠标的当前位置
  • mousemove(在 document 上): 计算鼠标移动了多远,并确定元素的位置
  • mouseup(在 document 上): 删除 document 上的事件处理程序
// 鼠标当前位置
let x = 0
let y = 0

// 查询元素
const ele = document.getElementById('dragMe')

// 处理鼠标按下事件
// 当用户拖动元素时触发
const mouseDownHandler = function (e) {
  // 获取当前鼠标位置
  x = e.clientX
  y = e.clientY

  // 将***附加到 document
  document.addEventListener('mousemove', mouseMoveHandler)
  document.addEventListener('mouseup', mouseUpHandler)
}

const mouseMoveHandler = function (e) {
  // 鼠标移动了多远
  const dx = e.clientX - x
  const dy = e.clientY - y

  // 设置元素的位置
  ele.style.top = `${ele.offsetTop + dy}px`
  ele.style.left = `${ele.offsetLeft + dx}px`

  // 重新分配鼠标位置
  x = e.clientX
  y = e.clientY
}

const mouseUpHandler = function () {
  // 移除 mousemove 和 mouseup 的处理程序
  document.removeEventListener('mousemove', mouseMoveHandler)
  document.removeEventListener('mouseup', mouseUpHandler)
}

ele.addEventListener('mousedown', mouseDownHandler)

查看效果