React中如何避免子div触发父元素的onDragLeave事件
React拖拽父容器避免子元素触发onDragLeave的解决方案
该问题的本质是拖拽事件的冒泡特性导致:当拖拽光标从父div移动到内部子div时,会先触发父div的onDragLeave事件(光标离开父元素的直接交互区域),随后子div触发的onDragEnter事件会冒泡到父元素,导致状态频繁切换,出现异常。
具体解决步骤
- 给父容器绑定React ref,用于后续判断元素从属关系
- 在
onDragLeave事件中判断光标即将进入的目标(event.relatedTarget)是否属于父容器的内部元素,如果是则不触发离开逻辑 - 补充
onDragOver事件阻止默认行为,保证拖放事件正常触发
修改后可运行代码
import React, { useState, useRef } from 'react'; const App = () => { const [dragOver, setDragOver] = useState(false); // 给父容器绑定ref const parentRef = useRef(null); const preventDefaults = (event) => { event.preventDefault(); event.stopPropagation(); }; const onDragEnter = (event) => { preventDefaults(event); if (!dragOver) { setDragOver(true); } }; const onDragLeave = (event) => { preventDefaults(event); // 核心判断:如果即将进入的元素是父容器的内部子元素,不触发离开逻辑 if (parentRef.current && !parentRef.current.contains(event.relatedTarget)) { setDragOver(false); } }; // 补充onDragOver阻止默认行为,拖放事件必须有这个才能正常触发 const onDragOver = (event) => { preventDefaults(event); }; return ( <div ref={parentRef} data-testid="document-upload" onDragEnter={onDragEnter} onDragLeave={onDragLeave} onDragOver={onDragOver} 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;
这个方案的核心逻辑是只有当光标完全移出父容器的范围时,才会重置拖拽悬停状态,移动到内部子元素时不会触发父容器的离开逻辑。
内容的提问来源于stack exchange,提问作者Jimmy
相关产品推荐
相关产品推荐

