以下代码是用react 书写, 但是hooks 方法里面是原生js书写. 也可适用于其他框架
import { useEffect } from "react";
/**
* @description 使用说明, 该hook是制,用于流程图拖拽
*
* 1. useDrag 方法: dragREf 传入需要抓取的Dom. 可传入class 或 id , '.drag' / '#drag'
*
* 注意: 在抓取拖拽的dom 中, 要设置自定义属性 data-key 字符串类型,否则不能传递数据
*
*
* 2. useDrop 方法: dropRef 放置dom, 传入 dropRef,如useDrag .
* callback 第二个参数为回调函数, 返回useDrag 携带的数据
*
* 注意: 在被放置的dom 中, 要设置自定义属性 data-key 字符串类型,否则不能传递数据, 一般放置的属性为该node的id
*
*
*
* 使用:
* - 在 需要拖拽的 jsx中调用
* useDrag('.drag')
*
* - 在放置数据的 jsx中 使用
* useDrop('.drop', (data) => {
console.log(JSON.parse(data))
})
*
* */
export const useDrag = (dragREf) => {
useEffect(() => {
// 获取拖动元素和放置目标
const draggables = document.querySelectorAll(dragREf);
// 监听拖动开始事件
draggables.forEach((item) => {
item.addEventListener("dragstart", function (event) {
const data = event.target.getAttribute("data-key");
// 可以在这里添加一些额外的数据到dataTransfer对象,例如标识拖动的元素ID
event.dataTransfer.setData("text/plain", data);
});
});
}, [dragREf]);
return {};
};
export const useDrop = (dropRef, callback) => {
useEffect(() => {
const droppables = document.querySelectorAll(dropRef);
// 监听放置目标上的拖过事件,允许放置
droppables.forEach((item) => {
item.addEventListener("dragover", function (event) {
event.preventDefault(); // 阻止默认处理以允许放置
});
});
// 监听放置事件
droppables.forEach((item) => {
item.addEventListener("drop", function (event) {
event.preventDefault(); // 阻止默认处理以允许放置
const draggedData = event.dataTransfer.getData("text/plain"); // 获取拖动的元素ID
callback(draggedData);
});
});
}, [callback, dropRef]);
return {};
};