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

如何在父级为可拖拽td的绝对定位#text元素中选中文本?

解决#text元素文本无法选中的问题

问题分析

父组件SelTd内的td元素设置了draggable="true"并绑定了onDragStart事件,事件里的e.preventDefault()会阻断文本选中的浏览器默认行为。当在#text上拖动鼠标时,事件冒泡到td触发拖拽逻辑,导致文本无法被选中。

可行解决方案

方案一:在拖拽事件中判断触发源

修改SelTd的onDragStart函数,检查事件触发元素是否属于#text区域,若是则跳过拖拽逻辑:

const SelTd = ({ children }: PropsWithChildren<any>) => {
    const ref = useRef(null)
    const onDragStart = useCallback((e: any) => {
        // 检查触发元素是否在#text范围内
        const textEl = document.getElementById('text');
        if (textEl && textEl.contains(e.target)) {
            return; // 不执行拖拽逻辑,允许文本选中
        }
        
        e.preventDefault()
        e.stopPropagation();
        ref.current && (ref.current.style.backgroundColor = 'yellow')
        setTimeout(() => {
            ref.current.style.backgroundColor = 'unset'
        }, 5 * 1000)
    }, [])
    return <td
        ref={ref}
        className="Td"
        draggable={true}
        onDragStart={onDragStart}
    >
        {children}
    </td>
}

方案二:阻止#text的事件冒泡到父元素

直接给#text元素添加draggable="false"和onMouseDown事件阻止冒泡,避免父级td的拖拽事件被触发:

export default function App() {
  return (
    <table>
      <tbody>
        <tr>
          <SelTd>
            <div className="Container">
              <div 
                className="Abs" 
                id="text" 
                draggable="false"
                onMouseDown={(e) => e.stopPropagation()}
              >
                text to select
              </div>
            </div>
          </SelTd>
          <td className="Td">2</td>
        </tr>
      </tbody>
    </table>
  );
}

此方案更直接:用户在#text上按下鼠标时,事件不会传递到父级td,拖拽逻辑不会被触发,文本选中的默认行为可正常执行。

方案三:结合CSS增强文本选中体验

给#text添加CSS属性显式声明文本可选中(需配合前两个JS方案使用,单独无法解决拖拽事件阻止选中的问题):

#text {
  user-select: text;
  -webkit-user-select: text;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 22:52:41