You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:15:01