认识下html5拖拽与拖放的API
拖拽流程
一个完整的drag and drop流程通常包含以下几个步骤:
1.设置可拖拽目标.设置属性draggable=”true”实现元素的可拖拽.
2.监听dragstart,通过DataTransfer设置拖拽数据
3.为拖拽操作设置反馈图标(可选)
4.设置允许的拖放效果,如copy,move,link
5.设置拖放目标,默认情况下浏览器阻止所有的拖放操作,所以需要监听dragenter或者dragover取消浏览器默认行为使元素可拖放.
6.监听drop事件执行所需操作
拖拽事件
以下是拖拽产生的一系列事件,拖拽事件产生时不会产生对应的鼠标事件.
dragstart:拖拽开始时在被拖拽元素上触发此事件,监听器需要设置拖拽所需数据,从操作系统拖拽文件到浏览器时不触发此事件.
dragenter:拖拽鼠标进入元素时在该元素上触发,用于给拖放元素设置视觉反馈,如高亮
dragover:拖拽时鼠标在目标元素上移动时触发.监听器通过阻止浏览器默认行为设置元素为可拖放元素.
dragleave:拖拽时鼠标移出目标元素时在目标元素上触发.此时监听器可以取消掉前面设置的视觉效果.
drag:拖拽期间在被拖拽元素上连续触发
drop:鼠标在拖放目标上释放时,在拖放目标上触发.此时监听器需要收集数据并且执行所需操作.如果是从操作系统拖放文件到浏览器,需要取消浏览器默认行为.
dragend:鼠标在拖放目标上释放时,在拖拽元素上触发.将元素从浏览器拖放到操作系统时不会触发此事件.
详细查看更多:
https://developer.mozilla.org…
结合实例 在线效果体验:drag-demo
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>拖动</title>
<style>
h2 {
font-size: 20px;
color: #0d88c1;
}
div#left,
div#right {
width: 120px;
float: left;
margin: 10px 100px 10px 0px;
height: 240px;
background-color: #dddddd;
overflow-y: auto;
}
div label {
font-size: 22px;
font-weight: bold;
width: 100%;
display: inline-block;
padding: 4px 0;
text-align: center;
margin: 0px 0 2px 0;
color: #fff;
background-color: #0d88c1;
}
.over {
border: 1px dashed red;
box-sizing: border-box;
}
</style>
</head>
<body>
<h2>拖放(Drag 和 drop)</h2>
<!-- 左边元素框 -->
<div id="left">
<label draggable="true">index1</label>
<label draggable="true">index2</label>
<label draggable="true">index3</label>
<label draggable="true">index4</label>
<label draggable="true">index5</label>
<label draggable="true">index6</label>
<label draggable="true">index7</label>
</div>
<!-- 右边元素框 -->
<div id="right"></div>
<script>
var moveItem = document.getElementsByTagName('label');
for (let i = 0; i < moveItem.length; i++) {
//动态设置label元素id
moveItem[i].setAttribute('id', 'label' + i);
moveItem[i].ondragstart = function (ev) {
//dataTransfer.setData() 方法设置被拖数据的数据类型和值
ev.dataTransfer.setData("id", this.id);
};
}
document.getElementById('right').ondragover = function (ev) {
ev.preventDefault(); //阻止向上冒泡
}
document.getElementById('right').ondragenter = function (ev) {
ev.target.classList.add('over')
}
document.getElementById('right').ondragleave = function (ev) {
ev.target.classList.remove('over')
}
document.getElementById('right').ondrop = function (ev) {
ev.preventDefault();
ev.target.classList.remove('over')
var id = ev.dataTransfer.getData('id');
var elem = document.getElementById(id); //当前拖动的元素
var toElem = ev.toElement.id; //放置位置
if (toElem == 'right') {
//如果为container,元素放置在末尾
this.appendChild(elem);
} else {
//如果为container里的元素,则插入该元素之前
this.insertBefore(elem, document.getElementById(toElem));
}
}
document.getElementById('left').ondragover = function (ev) {
ev.preventDefault(); //阻止向上冒泡
}
document.getElementById('left').ondragenter = function (ev) {
ev.target.classList.add('over')
}
document.getElementById('left').ondragleave = function (ev) {
ev.target.classList.remove('over')
}
document.getElementById('left').ondrop = function (ev) {
ev.preventDefault();
ev.target.classList.remove('over')
var id = ev.dataTransfer.getData('id');
var elem = document.getElementById(id);
var toElem = ev.toElement.id;
if (toElem == 'left') {
//如果为container,元素放置在末尾
this.appendChild(elem);
} else {
//如果为container里的元素,则插入该元素之前
this.insertBefore(elem, document.getElementById(toElem));
}
}
</script>
</body>
</html>
参考资料:
1、https://segmentfault.com/a/11…
2、http://www.zhangxinxu.com/wor…