HTML 拖放(Drag and Drop)接口使应用程序能够在浏览器中使用拖放功能。例如,用户可使用鼠标选择可拖拽(draggable)元素,将元素拖拽到可放置(droppable)元素,并释放鼠标按钮以放置这些元素。拖拽操作期间,会有一个可拖拽元素的半透明快照跟随着鼠标指针。

拖拽事件

拖拽的元素

让一个元素被拖拽需要添加 draggable 属性,再加上全局事件处理函数 ondragstart

1
<div id="box1" draggable="true"></div> <!-- 设置draggable="true"才能拖拽 -->
定义事件
1
2
3
4
5
6
7
8
9
10
11
12
13
const box1 = document.querySelector('#box1')
// 当用户开始拖拽一个元素或选中的文本时触发。
box1.addEventListener('dragstart',()=>{
console.log('拖拽开始');
})
// 当拖拽元素或选中的文本时触发。
box1.addEventListener('drag',()=>{
console.log('拖拽中');
})
// 当拖拽操作结束时触发 (比如松开鼠标按键或敲“Esc”键)。
box1.addEventListener('dragend',()=>{
console.log('停止拖拽');
})
定义拖拽数据

应用程序可以在拖拽操作中包含任意数量的数据项。每个数据项都是一个 string 类型,典型的 MIME 类型,如:text/html

1
2
3
4
5
6
box1.addEventListener('dragstart',(e)=>{
e.dataTransfer.setData("text/plain", e.target.innerText);
e.dataTransfer.setData("text/html", e.target.outerHTML);
e.dataTransfer.setData("text/uri-list", e.target.ownerDocument.location.href);
e.dataTransfer.setData('text','box1')
})
定义拖拽图片

拖拽过程中,浏览器会在鼠标旁显示一张默认图片。当然,应用程序也可以通过 setDragImage() 方法自定义一张图片。

1
2
3
4
5
box1.addEventListener('dragstart',(e)=>{
var img = new Image();
img.src = 'https://pic.imgdb.cn/item/62791e7a0947543129da29e9.jpg';
e.dataTransfer.setDragImage(img, 100, 100);
})
定义拖拽效果

dropEffect 属性用来控制拖放操作中用户给予的反馈。它会影响到拖拽过程中浏览器显示的鼠标样式。

effectAllowed 属性用来指定当元素被拖放式所允许的视觉效果

如果effectAllowed属性设定为具体的效果,则dropEffect 必须与之相等

1
2
3
4
box1.addEventListener('dragstart',(e)=>{ 
e.dataTransfer.effectAllowed = 'all' // all|none|copy|move|link|copyLink|copyMove|linkMove|uninitialized
e.dataTransfer.dropEffect = "copy"; // none|copy|move|link
})

目标元素

想要让一个元素变成可释放区域,该元素必须设置 ondragover 和 ondrop 事件处理程序属性

注意调用 preventDefault() 来阻止对这个事件的其它处理过程(如触点事件或指针事件)。

1
<div id="box2" ></div>
定义事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const box2 = document.querySelector('#box2')
// 当拖拽元素或选中的文本到一个可释放目标时触发。
box2.addEventListener('dragenter',(e)=>{
console.log('拖进目标');
})
// 当元素或选中的文本被拖到一个可释放目标上时触发(每100毫秒触发一次)。
box2.addEventListener('dragover',(e)=>{
e.preventDefault();
console.log('可释放');
})
// 当元素或选中的文本在可释放目标上被释放时触发。
box2.addEventListener('drop',(e)=>{
e.preventDefault();
console.log('在目标里释放');
})
// 当拖拽元素或选中的文本离开一个可释放目标时触发。
box2.addEventListener('dragleave',()=>{
console.log('离开目标');
})
获取拖拽数据
1
2
3
4
5
box2.addEventListener('drop',(e)=>{ 
e.preventDefault();
const data = e.dataTransfer.getData('text')
console.log('box2获取到了:'+data);
})
处理放置效果
1
2
3
box2.addEventListener('dragover',(e)=>{ 
e.dataTransfer.dropEffect = 'copy' // none|copy|move|link
}