请参阅下面的代码。它通过将要拖动的元素克隆并将其隐藏在下面来创建一个自定义的幻影图像。
我想以正确的方式进行操作,即使用带有useLayoutEffect的自定义react钩子对appendChild和removeChild进行操作,但由于setDataTransfer需要该事件而被卡住,并且还需要安装dom节点。
原本打算发布useCustomDragImage钩子尝试,但决定发布工作功能,因为它清楚地展示了我要执行的操作。
function handleDragStart(e) {
const { x, y, width, height } = e.target.getBoundingClientRect();
const { clientX, clientY } = e;
const crt = e.target.cloneNode(e.target);
crt.style.color = "white";
crt.style.height = `${height}px`;
crt.style.width = `${width}px`;
crt.style.position = "absolute";
crt.style.top = "0";
crt.style.left = "0";
crt.style.zIndex = "-1";
e.target.parentNode.appendChild(crt);
e.dataTransfer.setDragImage(crt, clientX - x, clientY - y);
setTimeout(() => crt.parentNode.removeChild(crt), 0);
}
编辑:(我的钩子尝试)
import { useLayoutEffect, useRef } from 'react'
export default function useGhost() {
const ref = useRef();
const parentRef = useRef();
useLayoutEffect(() => {
const element = ref.current;
const parent = parentRef.current;
if (!element) return;
console.log(parent)
// parent.appendChild(element);
return () => parent.removeChild(element);
})
function fromDomNode(e) {
const { x, y, width, height } = e.target.getBoundingClientRect();
const { x: mx, y: my } = e;
console.log(mx, my)
ref.current = e.target.cloneNode(e.target);
parentRef.current = e.target.parentNode;
console.log(parentRef.current)
console.log(ref.current)
const crt = ref.current;
// crt.style.backgroundColor = "red";
// crt.style.border = '1px dotted white';
crt.style.color = "white";
crt.style.height = `${height}px`;
crt.style.width = `${width}px`;
crt.style.position = "absolute";
crt.style.top = "0";
crt.style.left = "0";
crt.style.zIndex = "-1";
console.log(x, y, width, height)
parentRef.current.appendChild(crt); <---- Should go in useLayoutEffect() but can't setDragImage without mounting it first!
e.dataTransfer.setDragImage(crt, mx - x, my - y);
// setTimeout(function () {
// crt.parentNode.removeChild(crt);
// }, 1000);
}
return fromDomNode;
}