拖拽事件主要包括以下几种:
dragstart(拖拽开始):当用户开始拖拽一个元素时触发,通常在被拖拽的元素上绑定此事件。在该事件的处理函数中,可以设置被拖拽元素的一些属性或数据。
drag(拖拽移动):在拖拽过程中,随着鼠标或触摸屏的移动持续触发,通常在被拖拽元素上绑定此事件。在该事件的处理函数中,可以根据鼠标或触摸屏的位置更新被拖拽元素的状态。
dragenter(进入拖拽目标区域):当一个可拖拽的元素进入一个拖拽目标区域时触发,通常在拖拽目标元素上绑定此事件。在该事件的处理函数中,可以为拖拽目标元素添加一些视觉效果,以提示用户可以释放拖拽元素。
dragover(在拖拽目标区域中移动):当一个可拖拽的元素在一个拖拽目标区域中移动时持续触发,通常在拖拽目标元素上绑定此事件。在该事件的处理函数中,一般需要阻止默认的事件行为,以允许拖拽元素释放到该区域。
dragleave(离开拖拽目标区域):当一个可拖拽的元素离开一个拖拽目标区域时触发,通常在拖拽目标元素上绑定此事件。在该事件的处理函数中,可以移除之前添加的视觉效果。
drop(释放拖拽元素):当用户释放鼠标或触摸屏时,在拖拽目标区域内触发此事件。通常在拖拽目标元素上绑定此事件。在该事件的处理函数中,可以处理释放拖拽元素后的相关操作,如更新页面内容或重新排列元素顺序。
这些事件可以结合使用,以实现各种拖拽交互功能,例如拖拽排序、拖拽放置等。
1、演示
2、问题
1、怎样让元素变得可拖拽
给元素加上 draggable 属性,值为 true 即可
<div draggable="true" class="list-item">1</div>
2、拖拽的时候本身元素的样式得变
准备样式
.list-item.moving { background-color: transparent; color: transparent; border: 1px solid #ccc; }
3、什么时候产生排序
拖拽的时候把拖拽对象放到了某些元素之上,这里就要监听拖拽进入事件
el.addEventListener('dragenter', function (e) {})
3、 源码及注释
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.list-item {
background-color: #266fff;
border-radius: 5px;
color: #fff;
width: 250px;
padding: 5px;
margin-bottom: 10px;
}
.list-item.moving {
background-color: transparent;
color: transparent;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<div class="list">
<div draggable="true" class="list-item">1</div>
<div draggable="true" class="list-item">2</div>
<div draggable="true" class="list-item">3</div>
<div draggable="true" class="list-item">4</div>
<div draggable="true" class="list-item">5</div>
</div>
</body>
<script>
// 拖拽排序在很多站点里面是非常常见的,使用的API就是一个拖拽API
// 1、让元素变的可拖拽 找到这些元素,给这些元素加上 draggable 属性,值为true,这样就变得可拖拽了
// 2、拖拽的时候样式得变 class为moving的样式
const list = document.querySelector('.list')
// 用事件委托的方式 给父元素绑定事件
list.addEventListener('dragstart', function (e) {
// 当拖拽开始的时候要找到拖拽的那个元素给他添加类样式
// 为什么要用setTimeout,不用的话拖拽的那个元素也会变成虚线(就是添加了类样式后的样子),
// 它的样式取决于拖拽开始时候元素本身的样式,需要在拖拽开始的时候保持原来的样式 把它变成异步的
setTimeout(() => {
e.target.classList.add('moving')
}, 0)
sourceNode = e.target
})
// 用来记录当前拖拽的是哪个元素
let sourceNode = null
// 3、什么时候产生排序?拖拽的时候把拖拽对象放到了某些元素之上,这里就要监听拖拽进入事件
list.addEventListener('dragenter', function (e) {
e.preventDefault()
// 排除掉一些情况,比如拖拽的时候进入了父元素 或者 是本身自己
if (e.target == list || e.target == sourceNode) return
const children = [...list.children]
// 通过所处元素的下标来判断是上方还是下方
const sourceIndex = children.indexOf(sourceNode)
const targetIndex = children.indexOf(e.target)
console.log(sourceIndex, targetIndex)
// 4、当拖拽的元素进入到别的元素身上的时候,要做的一些事情
if (sourceIndex < targetIndex) {
// console.log('下方')
// 插入到那个元素下一个元素之前
list.insertBefore(sourceNode, e.target.nextElementSibling)
} else {
// console.log('上方')
list.insertBefore(sourceNode, e.target)
}
console.log(sourceIndex)
})
// 拖拽完毕 松开鼠标
list.addEventListener('dragend', function (e) {
// 移除掉类样式即可
sourceNode.classList.remove('moving')
})
</script>
</html>