diff --git a/src/components/practice/InputArea.tsx b/src/components/practice/InputArea.tsx index 92c0562..0d8ab19 100644 --- a/src/components/practice/InputArea.tsx +++ b/src/components/practice/InputArea.tsx @@ -42,6 +42,13 @@ export function InputArea({ const newInput = [...userInput] + // 输入法组合期间,只更新当前输入框的值,不做任何跳转 + if (isComposing) { + newInput[index] = value + onInputChange(newInput) + return + } + // 处理多字符输入(连续输入或粘贴) if (value.length > 1) { const chars = value.split('') diff --git a/src/pages/ProcessPracticePage.tsx b/src/pages/ProcessPracticePage.tsx index a25e3a2..7430f87 100644 --- a/src/pages/ProcessPracticePage.tsx +++ b/src/pages/ProcessPracticePage.tsx @@ -212,9 +212,29 @@ export default function ProcessPracticePage() { const handleCompositionEnd = useCallback(() => { setIsComposing(false) - // 输入法确认后根据最新快照重新验证 + // 输入法确认后,需要将当前输入框中的所有字符分散到后续输入框 requestAnimationFrame(() => { - validateInput(latestInputRef.current) + const currentInput = latestInputRef.current + // 找到第一个有内容且长度>1的输入框(输入法组合的结果) + const composedIndex = currentInput.findIndex((char) => char.length > 1) + + if (composedIndex !== -1) { + const composedText = currentInput[composedIndex] + const chars = composedText.split('') + const newInput = [...currentInput] + + // 将组合的字符分散到后续输入框 + for (let i = 0; i < chars.length && composedIndex + i < newInput.length; i++) { + newInput[composedIndex + i] = chars[i] + } + + latestInputRef.current = newInput + setUserInput(newInput) + validateInput(newInput) + } else { + // 没有多字符组合,直接验证当前输入 + validateInput(currentInput) + } }) }, [validateInput])