写在前面

这个需求的实现重点就是鼠标 mouse 的三个事件的监听处理。即 mousedownmousemovemouseup

并且,可以被拖拽随意移动的元素一般是绝对定位的元素。

实现方法

  1. <body>
  2. <div id="xxx"></div>
  3. </body>
  1. #xxx{
  2. position: absolute;
  3. width: 100px;
  4. height: 100px;
  5. border: 1px solid red;
  6. }
  1. let dragging = false;
  2. let position = [];
  3. xxx.addEventListener('mousedown',(e)=>{
  4. dragging = true;
  5. position = [e.clientX, e.clientY];
  6. })
  7. document.addEventListener('mousemove',(e)=>{
  8. if(!dragging) return;
  9. const x = e.clientX;
  10. const y = e.clientY;
  11. const deltaX = x - position[0];
  12. const deltaY = y - position[1];
  13. console.log(deltaX,deltaY);
  14. const left = parseInt(xxx.style.left || 0);
  15. const top = parseInt(xxx.style.top || 0);
  16. xxx.style.left = left + deltaX + 'px';
  17. xxx.style.top = top + deltaY + 'px';
  18. // 为了更好的性能,不要用left,用transform(x,y)
  19. position = [x,y];
  20. })
  21. document.addEventListener('mouseup',(e)=>{
  22. dragging = false;
  23. })

注意事项:

  1. style.left 得到的是带有 px 单位的值,需要进行数值转化。
  2. style.left 的值可能为 undefined,parseInt(undefined) = NaN,因此记得保留值 || 0。
  3. mousedown 必须是绑定在 xxx 元素上,为了使得移动流畅,mousemove 一般绑定在 document 上,mouseup也是。
  4. 为了性能,移动元素位置的时候要用transform 代替绝对定位的left