一、拖拽事件
1、拖拽元素
- drag:拖拽事件,当元素正在被被拖拽时触发
- dragstart:拖拽开始事件,拖拽元素开始拖拽时触发
- dragend:拖拽结束事件
2、目标元素
- dragenter:拖拽元素进入目标元素事件
- dragover:拖拽元素在目标元素中事件
- dragleave:拖拽元素离开目标元素事件
- drop:拖拽元素或文本放置在目标元素区域时触发
3、事件顺序
drapstart->dragenter->dragover->dragleave->dragend
4、拖拽事件对象
dataTransfe
①dropEffect:拖放的操作类型,决定浏览器如何显示鼠标形状,取值为:copy、move、link、none
注意:只能在dragover事件这种设置该属性,当显示禁止的指针样式时,将无法触发目标元素的drop事件
②effectAllowed:指定允许的操作,取值为:move、link、copy、copylink、copymove、linkmove、all、none
注意:只能在dragstart事件中设置该属性
二、拖拽案例
如上图实现拖拽排序功能:
1、准备好需要排序的元素,并给他们添加draggable属性,值为true
<head>
...
<style>
.container {
padding: 0;
margin: 100px 0 0 100px;
}
.item {
width: 300px;
height: 30px;
margin-bottom: 3px;
line-height: 30px;
size: 20px;
padding-left: 10px;
border-radius: 3px;
background-color: rgb(3, 85, 3);
/* border: 1px dashed 3px white; */
}
.moving {
border: 1px dashed rgb(215, 214, 214);
background-color: transparent;
}
</style>
</head>
<body>
<div class="container">
<div draggable="true" class="item hh" data-self="888">1</div>
<div draggable="true" class="item">2</div>
<div draggable="true" class="item">3</div>
<div draggable="true" class="item">4</div>
<div draggable="true" class="item">5</div>
<div draggable="true" class="item">6</div>
</div>
</body>
2、监听开始拖拽事件:dragstart
var dragItems = document.querySelector(".container");
var dragItem;
dragItems.addEventListener("dragstart", (e) => {
//拖拽开始设置原来位置元素样式
dragItem = e.target;
//直接设置,会导致原位置和跟随鼠标拖动元素的样式都发生改变,setTime在拖拽之后,再改变原位置的样式
setTimeout(() => {
dragItem.classList.add("moving");
}, 0);
//e.dataTransfer.setData('text','hello Roper')
//console.log(e.dataTransfer.getData('text'));
e.dataTransfer.effectAllowed = 'move'
})
3、监听拖拽结束事件:dragenter ①特殊情况处理 排除自身和父元素 ②获取拖拽元素和目标元素的order,利用insertbefore实现元素的拖拽
dragItems.ondragenter = (e) => {
e.preventDefault();
//特殊情况处理:1、拖拽到父元素 2、拖拽到自身
if (e.target === dragItems || dragItem === e.target) {
return;
}
var childrens = [...dragItems.children];
//拖拽元素下标
var sourcesIndex = childrens.indexOf(dragItem);
//目标元素下标
var targetIndex = childrens.indexOf(e.target);
if (sourcesIndex > targetIndex) {
dragItems.insertBefore(dragItem, e.target);
} else {
dragItems.insertBefore(
dragItem,
e.target.nextElementSibling,
);
}
// console.log(e.target);
};
4、问题处理
①去掉原拖拽元素的样式
dragItems.ondragend = function (e) {
dragItem.classList.remove("moving");
};
②拖动元素会自动回到原来位置:浏览器默认不允许元素拖动到自身,需要去dragenter和dragover中阻止默认事件
dragItems.ondragenter = (e) => {
e.preventDefault();
}
dragItems.ondragover = (e) =>{
e.preventDefault();
};
③鼠标样式设置(effectAllowed只能在dragstart中设置)
dragItems.addEventListener("dragstart", (e) => {
e.dataTransfer.effectAllowed = 'move'
});