研究了哈拖拽替换dom节点,这里记录下哈,希望对需要的朋友有所帮助!
这里我使用了两种方式尝试过:
1,使用draggable插件
2,直接给要拖拽的元素添加draggable="true"
draggable插件
插件效果就直接查看demo
1、安装
npm install @shopify/draggable@next --save
2、引入
import { Swappable, Plugins } from '@shopify/draggable'
<div class="GridLayout">
<div class="item-box">
<div class="content-box Block--isDraggable">盒子1</div>
</div>
<div class="item-box">
<div class="content-box Block--isDraggable">盒子2</div>
</div>
<div class="item-box">
<div class="content-box Block--isDraggable">盒子3</div>
</div>
</div>
const containers = document.querySelectorAll('.GridLayout') // 克隆节点新增追加在GridLayout里面
const draggable = new Swappable(containers, {
draggable: '.Block--isDraggable', // 可拖拽的节点
mirror: {
appendTo: 'GridLayout',
constrainDimensions: true
},
plugins: [Plugins.ResizeMirror]
})
draggable.on('mirror:created', (evt) => {
console.log(evt)
})
draggable属性
在拖动目标上触发(源目标元素):
ondragstart - 用户开始拖动元素
ondrag - 元素正在被拖动
ondragend - 用户结束元素拖动
释放目标时触发的事件:
ondragenter - 当被拖动的对象进入其容器范围内时触发
ondragover - 当被拖动的对象在另一对象容器范围内拖动时触发
ondragleave - 当被拖动的对象离开其容器范围内时触发
ondrop - 在一个拖动过程中,释放鼠标键时触发
注意: 在拖动元素时,每隔 350 毫秒会触发 ondrag 事件。
相同父元素拖拽替换
<div id="drag-box">
<div draggable="true">盒子1</div>
<div draggable="true">盒子2</div>
<div draggable="true">盒子3</div>
<div draggable="true">盒子4</div>
</div>
// 用来存取被拖拽的节点
let draggedNode = null
// 获取可拖拽节点
const dragNodes = document.querySelectorAll('div[draggable="true"]')
// 给可拖拽节点绑定事件
dragNodes.forEach((item,index) => {
item.ondragstart = () => {
draggedNode = item
}
// 默认情况下,数据/元素不能在其他元素中被拖放,也就是会阻止你做drop操作,所以取消其默认行为
item.ondragover = e => {
e.preventDefault()
}
// 被拖拽的节点,被释放后进行节点替换
item.ondrop = e => {
if (draggedNode !== null && draggedNode !== item) {
const temp = document.createElement('div')
const dragBox = document.getElementById('drag-box')
dragBox.replaceChild(temp, e.target)
dragBox.replaceChild(e.target, draggedNode)
dragBox.replaceChild(draggedNode, temp)
}
}
})
不同父元素拖拽替换
<div class="GridLayout">
<div class="item-box">
<div class="content-box Block--isDraggable" draggable="true">
<div>盒子1</div>
<div>盒子1</div>
</div>
</div>
<div class="item-box">
<div class="content-box Block--isDraggable" draggable="true">
<div>盒子2</div>
<div>盒子2</div>
</div>
</div>
<div class="item-box">
<div class="content-box Block--isDraggable" draggable="true">
<div>盒子3</div>
<div>盒子3</div>
</div>
</div>
</div>
// 用来存取被拖拽的节点
let draggedNode = null
// 获取可拖拽节点
const dragNodes = document.querySelectorAll('div[draggable="true"]')
// 给可拖拽节点绑定事件
dragNodes.forEach(item => {
item.ondragstart = () => {
draggedNode = item
}
// 默认情况下,数据/元素不能在其他元素中被拖放,也就是会阻止你做drop操作,所以取消其默认行为
item.ondragover = e => {
e.preventDefault()
}
// 被拖拽的节点,被释放后进行节点替换
item.ondrop = e => {
if (draggedNode !== null && draggedNode !== item) {
const temp = document.createElement('div')
const aParent = draggedNode.parentNode
// 拖拽时找到需要被替换的目标节点
const target = e.path.filter(item => item.draggable)[0]
if (!target) return
let bParent
if (aParent) {
bParent = target.parentNode
if (bParent) {
bParent.replaceChild(temp, target)
aParent.replaceChild(target, draggedNode)
bParent.replaceChild(draggedNode, temp)
}
}
}
}
})
关于draggable
属性其他事件操作点我