记录一下拖拽DOM,并传递数据通用方法

55 阅读1分钟

以下代码是用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 {};
};