发布于 2026-02-15
在 iOS Safari 中有一个奇怪的问题,在输入框做复杂的编辑,忽然发现整个网页所有按钮都无法点击了。
经排查,使用粘贴功能时,该问题触发的频率更高,甚至达到必现。典型场景:长文本粘贴、连续粘贴、粘贴后紧接着继续输入等。
该问题是 iOS Safari 在粘贴过程中的焦点状态不稳定导致。需要在粘贴后失焦时,轻量恢复焦点与选区,保证用户粘贴后的光标位置正确。
思路:只在「粘贴前已聚焦」且「粘贴后失焦」时介入。
export function restoreIOSPasteFocus(target: HTMLTextAreaElement | HTMLInputElement | null) {
// iOS Safari 粘贴后可能导致输入框失焦与选区丢失,只在「粘贴前已聚焦」且「粘贴后失焦」时介入修复
if (!target) return;
if (typeof navigator === 'undefined') return;
if (typeof document === 'undefined') return;
if (!/iP(ad|hone|od)/.test(navigator.userAgent)) return;
if (document.activeElement !== target) return;
// 先缓存选区,避免后续聚焦时位置被重置
const start = target.selectionStart;
const end = target.selectionEnd;
requestAnimationFrame(() => {
// 等粘贴流程结束后再判断是否失焦
if (document.activeElement === target) return;
target.focus();
requestAnimationFrame(() => {
// 仅在成功回焦后恢复选区
if (document.activeElement !== target) return;
if (start !== null && end !== null) {
target.setSelectionRange(start, end);
}
});
});
}
该方法只影响 iOS,不影响其他平台的原始行为。
在 textarea/input 的 onPaste 上调用即可:
<textarea
value={form.content}
onChange={(e) => setForm({ ...form, content: e.target.value })}
onPaste={(e) => restoreIOSPasteFocus(e.currentTarget)}
/>