请查看此代码沙盒。
我有一个父div,它需要处理可拖动事件(例如当文件被拖动到它上面时)。调用onDragEnter
时,我希望背景颜色发生变化。但是,我有一个子div,当它悬停在上面时,会调用父div的onDragLeave
事件。我曾尝试将ref与这个子div一起使用,以确定事件目标是否包含在子div中,但这似乎不起作用。如何避免React中的子div调用onDragLeave
事件?谢谢
import React, { useState } from 'react';
const App = () => {
const [dragOver, setDragOver] = useState(false);
const preventDefaults = (event) => {
event.preventDefault();
event.stopPropagation();
};
const onDragEnter = (event) => {
preventDefaults(event);
console.log('ENTER');
if (!dragOver) {
setDragOver(true);
}
};
const onDragLeave = (event) => {
preventDefaults(event);
console.log('LEAVE');
setDragOver(false);
};
return (
<div
data-testid="document-upload"
onDragEnter={onDragEnter}
onDragLeave={onDragLeave}
style={{
background: dragOver ? 'green' : 'red',
height: '20rem',
width: '20rem',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<div
style={{ border: '2px solid blue', height: '10rem', width: '10rem' }}
/>
</div>
);
};
export default App;
最简单的方法是在子<div>
的style
属性中设置pointerEvents: "none"
,以便忽略该div上所有与指针相关的事件。不过,这会带来一些限制,比如你不能将点击事件绑定到子分区
如果这不符合应用程序的限制,则可以修改onDragLeave
处理程序以检查事件的relatedTarget
(请参阅文档)。如果拖动离开父级<div>
,但输入父级的子级,则currentTarget
(即父级<div>
)将包含relatedTarget
(即子级div)(参见文档)
以下是应该工作的代码:
const onDragLeave = (event) => {
preventDefaults(event);
// This condition will be true when the drag leaves the parent for a child,
// but false when the drag leaves the parent for somewhere else.
if (event.currentTarget.contains(event.relatedTarget)) return;
console.log("LEAVE");
setDragOver(false);
};
请参阅此代码沙盒。