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

如何在hello-pangea/dnd中排除指定区域的拖拽触发?

解决方案

方法1:在SVG区域阻止拖拽事件冒泡

给SVG容器添加onMouseDown事件阻止冒泡,同时保留手柄元素的stopPropagation,确保SVG内的操作不会触发外层的整体拖拽:

修改TimelineAxis组件的关键代码:

const handleSvgMouseDown = (event: React.MouseEvent<SVGSVGElement>) => {
  event.stopPropagation();
};

return (
  <svg 
    ref={svgRef} 
    width="100%" 
    height="60" 
    onClick={handleSvgClick}
    onMouseDown={handleSvgMouseDown} // 添加这行
  >
    {/* 原有元素保持不变 */}
    <circle cx={scale(start)} cy="30" r="8" fill="var(--primary-color, blue)" cursor="ew-resize" onMouseDown={handleDrag(true)} />
    <circle cx={scale(end)} cy="30" r="8" fill="var(--primary-color, blue)" cursor="ew-resize" onMouseDown={handleDrag(false)} />
    {/* 原有元素保持不变 */}
  </svg>
);

方法2:限制拖拽手柄的作用范围

不要将dragHandleProps绑定到整个折叠区域,而是只绑定到非SVG的部分,比如单独的标题区域:

修改SpanSection组件的header部分:

export const SpanSection: React.FC<SpanSectionProps> = ({isExpanded, onToggle, timePeriod, dragHandleProps, onDateChange}) => {
  // 原有逻辑保持不变

  return (
    <div className="span-section" style={{ width: '100%' }}>
      <CollapsibleSection 
        header={
          <div style={{ display: 'flex', alignItems: 'center', width: '100%' }}>
            {/* 仅让这个区域作为整体拖拽的手柄 */}
            <div {...dragHandleProps} style={{ cursor: 'grab', padding: '0 12px' }}>
              <span>时间范围</span>
            </div>
            {/* SVG区域独立处理自身交互 */}
            <TimelineAxis
              fixedStartDate={timePeriod.startDate}
              fixedEndDate={timePeriod.endDate}
              initialStartDate={localTimePeriod.startDate} 
              initialEndDate={localTimePeriod.endDate} 
              onDateChange={handleDateChange}
            />
          </div>
        }
        isExpanded={isExpanded} 
        onToggle={onToggle}
        {/* 不再将dragHandleProps传给整个CollapsibleSection */}
      >
        {/* 原有内容保持不变 */}
      </CollapsibleSection>
    </div>
  );
};

方法3:使用官方cancel属性排除SVG区域

利用hello-pangea/dnd的cancel属性,直接指定需要排除拖拽触发的元素选择器:

  1. 给SVG添加类名:
<svg ref={svgRef} className="timeline-svg" width="100%" height="60" onClick={handleSvgClick}>
  1. 修改DraggableSections中的Draggable组件:
<Draggable 
  key={section.id} 
  draggableId={section.id} 
  index={index}
  cancel=".timeline-svg" // 添加这行,指定排除的选择器
>
  {(provided, snapshot) => (
    <div ref={provided.innerRef} {...provided.draggableProps} className={`draggable-section ${snapshot.isDragging ? 'is-dragging' : ''}`}>
      <SectionComponent {...sectionsProps[section.id]} dragHandleProps={provided.dragHandleProps} />
    </div>
  )}
</Draggable>

该属性会让指定选择器内的元素完全跳过拖拽逻辑,保留自身的交互行为。


内容的提问来源于stack exchange,提问作者Santeau

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 09:59:56