文章目录
- 功能一:使用H5 拖放事件实现一个拖拉拽
- ✏️ 拖放逻辑以及流程
- 1. 基本布局-- 使用for遍历出列表并添加draggable 属性设置为 true,把元素设置为可拖放
- 2. 添加拖动开始事件dragstart,拖动结束事件dragenter
- 3. 2中视觉上拖拽不明显,添加拖动时候原始数据隐藏(opacity: 0;),拖宅结束后释放隐藏元素到最新位置
- ✏️ 九宫格拖拽
- 展示效果
- ✏️ 完整代码
注释: 接上期[管理系统之增删改查],(https://blog.csdn.net/men_gqi/article/details/131718259?spm=1001.2014.3001.5501)这篇实战一些插件和api
屏幕录制2023-07-21 14.57.01
知识备注:
拖动事件:dragstart、drag、dragend
放置事件:dragenter、dragover、drop
从拖动元素放置到目标元素上依次触发
dragstart(触发拖动事件)—> dragenter(拖拉进入当前节点时触发当前节点) --------->dragover(增加视觉感这个博主总结的挺详细的) ----> dragend(当拖动停止时事件)
setTimeout(() => {
e.target.classList.add('moveing')//元素正处于拖拽中时候,原始原素设置为透明状态
console.log(7,e.target)
}, 0)
e.target.classList.remove('moveing')
function dragover(e) {
console.log(e.dataTransfer)
e.preventDefault()
e.dataTransfer.dropEffect = 'move'
}
<template>
<div class="dragH5">
<div class="item" v-for="(item, i) in drag.list" :key="item.id" draggable="true" @dragstart="dragstart($event, i)"
@dragenter="dragenter($event, i)" @dragend="dragend" @dragover="dragover">
{{ item.name }}
</div>
<div class="box-card">
<div class="item" v-for="(item, i) in drag.list2" :key="item.id" draggable="true" @dragstart="dragstart2($event, i)"
@dragenter="dragenter2($event, i)" @dragend="dragend2" @dragover="dragover2">
{{ item.name }}
</div>
</div>
</div>
</template>
<script setup>
import { reactive } from 'vue'
const drag = reactive({
list: [
{ name: 'a', id: 1 },
{ name: 'b', id: 2 },
{ name: 'c', id: 3 },
{ name: 'd', id: 4 },
{ name: 'e', id: 5 },
],
list2: [
{ name: 'a', id: 11 },
{ name: 'b', id: 12 },
{ name: 'c', id: 13 },
{ name: 'd', id: 14 },
{ name: 'e', id: 15 },
{ name: 'f', id: 16 },
{ name: 'g', id: 17 },
{ name: 'h', id: 18 },
{ name: 'i', id: 19 },
{ name: 'j', id: 110 },
{ name: 'k', id: 111 },
{ name: 'l', id: 112 },
]
})
// 列表拖拽
let dragIndex = 0//记录原始拖拽元素下标
function dragstart(e, index) {
e.stopPropagation()//方法阻止事件冒泡
dragIndex = index//找到当前拖动元素下标
setTimeout(() => {
e.target.classList.add('moveing')//元素正处于拖拽中时候,原始原素设置为透明状态
console.log(7,e.target)
}, 0)
}
function dragenter(e, index) {//拖拉进入当前节点时触发当前节点
e.preventDefault()//阻止默认活动
// 拖拽到原位置时不触发
if (dragIndex !== index) {
const source = drag.list[dragIndex];//找到当前拖动元素原始列表中位置
drag.list.splice(dragIndex, 1);//删除原始位置
drag.list.splice(index, 0, source);//添加到新的位置
dragIndex = index // 更新节点位置
}
}
function dragover(e) {
console.log(e.dataTransfer)
e.preventDefault()
e.dataTransfer.dropEffect = 'move'
}
function dragend(e) {//元素拖拽结束
e.target.classList.remove('moveing')//元素拖拽结束,去掉设置透明状态的class
}
//九宫格使用
let dragIndex2 = 0//记录原始拖拽元素下标
function dragstart2(e, index) {
e.stopPropagation()//方法阻止事件冒泡
dragIndex = index//找到当前拖动元素下标
setTimeout(() => {
e.target.classList.add('moveing')//元素正处于拖拽中时候,原始原素设置为透明状态
console.log(7,e.target)
}, 0)
}
function dragenter2(e, index) {//拖拉进入当前节点时触发当前节点
e.preventDefault()//阻止默认活动
// 拖拽到原位置时不触发
if (dragIndex !== index) {
const source = drag.list[dragIndex];//找到当前拖动元素原始列表中位置
drag.list.splice(dragIndex, 1);//删除原始位置
drag.list.splice(index, 0, source);//添加到新的位置
dragIndex = index // 更新节点位置
}
}
function dragover2(e) {
console.log(e.dataTransfer)
e.preventDefault()
e.dataTransfer.dropEffect = 'move'
}
function dragend2(e) {//元素拖拽结束
e.target.classList.remove('moveing')//元素拖拽结束,去掉设置透明状态的class
}
</script>
<style lang="scss" scoped>
.dragH5{
overflow-y: scroll;
height: calc(100vh - 49px);
}
// 列表拖拽
.item {
width: 200px;
height: 40px;
line-height: 40px;
// background-color: #f5f6f8;
background-color: skyblue;
text-align: center;
margin: 10px;
color: #fff;
font-size: 18px;
}
.container {
position: relative;
padding: 0;
}
.moveing {
opacity: 0;
}
// 卡片拖拽
.box-card {
width: 480px;
height: 500px;
display: flex;
margin-left: 20px;
flex-wrap: wrap;
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
.item{
width: 100px;
height: 50px;
margin-left: 20px;
}
}
</style>