React中如何实现输入框聚焦时自动高亮选中内部文本?
React 输入框聚焦自动全选文本失效解决方案
失效原因
直接在onFocus事件回调中调用select()不生效,核心是事件执行时序问题:
- 鼠标点击触发输入框聚焦时,
focus事件触发后,浏览器还会执行后续mouseup事件的默认逻辑,该逻辑会主动清除输入框内的文本选中状态,提前执行的select()效果会被直接覆盖。 - React合成事件和原生事件的触发时序差,也可能导致DOM还没完成聚焦状态更新就调用
select(),无法触发选中效果。
可直接复用的实现方案
方案1:延迟调用select(兼容所有聚焦场景,优先用)
将select()逻辑放到宏任务队列中,等当前所有同步事件、浏览器默认行为执行完成后再触发选中,不需要额外绑定其他事件,兼容鼠标点击、Tab键切换聚焦、代码主动调用focus()所有场景:
import { useRef } from 'react'; export default function TextInput() { const inputRef = useRef(null); const handleFocus = () => { // 延迟0ms即可,仅为了错开浏览器默认事件执行时机 setTimeout(() => { inputRef.current?.select(); }, 0); }; return ( <input ref={inputRef} type="text" defaultValue="测试文本内容" onFocus={handleFocus} /> ); }
方案2:拦截mouseup默认行为(仅处理点击场景时用)
如果只需要覆盖鼠标点击触发的聚焦场景,可以在mouseup阶段阻止浏览器默认的清除选中逻辑,注意要加标记避免影响输入框已聚焦后的点击操作:
import { useRef, useState } from 'react'; export default function TextInput() { const inputRef = useRef(null); const [isFirstFocus, setIsFirstFocus] = useState(true); const handleMouseUp = (e) => { if (isFirstFocus) { e.preventDefault(); inputRef.current?.select(); setIsFirstFocus(false); } }; const handleBlur = () => { setIsFirstFocus(true); }; return ( <input ref={inputRef} type="text" defaultValue="测试文本内容" onMouseUp={handleMouseUp} onFocus={() => inputRef.current?.select()} onBlur={handleBlur} /> ); }
避坑提醒
- 不要用
onClick事件代替onFocus实现选中逻辑:键盘Tab聚焦、代码主动触发聚焦时不会触发点击事件,会漏掉场景。 - 受控组件场景下,要确保
value值已经渲染到DOM后再调用select(),否则会出现选中空内容的问题。 - 不要在
mousedown事件里调用select(),该阶段输入框还没完成聚焦,调用不会生效。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

