如何在父级为可拖拽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
相关产品推荐
相关产品推荐

