js-draggable实现拖拽元素交换位置

研究了哈拖拽替换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属性其他事件操作点我


 上一篇
linux的基本操作命令 linux的基本操作命令
1、cd命令 功能说明:切换目录。 举 例: 却换到根目录 :cd / 切换到上次目录: cd - 2、 ls命令 功能说明:列出目录内容。 举 例: 列出/var目录的文件和目录的信息 :ls –l /var; 最常用方式 ls
2022-05-15
下一篇 
React的Hooks函数useRef和useImperativeHandle React的Hooks函数useRef和useImperativeHandle
在之前的React的类组件ref使用笔记中,介绍了在类组件中使用ref,本笔记主要记录在函数组件中使用ref,在函数组件中是不能直接使用ref的,而是要使用Hook函数useRef来实现类似在类组件中ref的功能。 初识useRef use
2022-04-12
  目录