先看看实现效果图, 模拟拖拽最终效果和在桌面上移动文件夹的效果类似
原理介绍
鼠标按下时,拖拽开始。鼠标移动时,被拖拽元素跟着鼠标一起移动。鼠标抬起时,拖拽结束
所以,拖拽的重点是确定被拖拽元素是如何移动的
假设,鼠标按下时,鼠标对象的clientX和clientY分别为x1和x2。元素距离视口左上角x轴和y轴分别为x0和y0
鼠标移动的某一时刻,clientX和clientY分别为x2和y2
所以,元素移动的x轴和y轴距离分别为x2-x1和y2-y1
元素移动后,元素距离视口左上角x轴和y轴的位置分别为
代码实现
将上面的原理用代码实现如下
鼠标按下时,初始态的x0和y0分别用offsetLeft
和offsetTop
表示
鼠标移动时,瞬时态的x和y分别赋值为定位后元素的left和top
代码优化
使用上面的代码时,会出现一个问题。当鼠标拖动的太快,比onmousemove
事件的触发间隔还要快时,鼠标就会从元素上离开。这样就停止了元素的拖拽过程
此时,如果把mousemove
和mouseup
事件都加在document
上时,即可解决
拖拽冲突
由于文字和图片默认支持原生拖放,如果将原生拖放和模拟拖拽掺杂在一起,将造成与预想效果不符的情况
如果拖放的元素内容存在文字,且文字被选中会触发文字的原生拖放效果
在文字上面双击鼠标,即可选中文字,再移动鼠标时,会触发文字的原生拖放效果,如下所示
只要在onmousedown
事件阻止浏览器的默认行为即可