ChatGPT都踩过的坑:AI对话框中文输入法完美解决方案
在AI时代,输入框中文输入法处理是一个常见的问题。本文将介绍如何解决这个问题,并提供详细的解决方案。
在我们开发 AI 聊天框的时候,经常会遇到输入框中文输入法处理的问题。
比如:中文输入法输入英文的时候,按下回车键会直接发送消息
在早些的 ChatGPT、POE 等 AI 聊天框中,都会出现这个问题。那我们如何解决呢?
产生原因
在解释解决方案之前,我们需要先了解这个问题产生的原因。当我们使用中文(或日文、韩文等)输入法时,实际上文字输入经历了一个叫做"组合输入"(Composition)的过程:
- 组合开始(CompositionStart):当我们切换到输入法并开始输入时,浏览器会触发
compositionstart
事件 - 组合更新(CompositionUpdate):当我们输入拼音(如"nihao")并且文字还未确认时,浏览器会不断触发
compositionupdate
事件 - 组合结束(CompositionEnd):当我们按下空格或回车确认文字(如"你好")时,浏览器会触发
compositionend
事件
问题就出在这个过程中:在使用中文输入法输入英文单词时,如果用户按下回车键,会同时触发两个事件:
- 输入法认为用户要确认当前输入,触发
compositionend
事件 - 键盘按下回车键,触发
keydown
事件(Enter键)
而在许多 AI 聊天应用中,开发者通常会监听回车键来发送消息。这就导致当用户仅仅想要确认输入文字时,消息却被意外发送出去了。
解决方案
解决这个问题有几种方法,最常见的有以下几种:
1. 使用 isComposing 属性检测
在 React 中,我们可以利用键盘事件的 isComposing
属性来判断当前是否处于组合输入状态:
const onSubmit = async (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
// 如果正在输入法组合状态,不发送消息
if ((e as unknown as KeyboardEvent).isComposing) {
return
}
// 检查是否按下了Enter键(且没有按Shift键)
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
// 发送消息逻辑
sendMessage();
// 清空输入框
setInputValue('');
}
}
注意上面代码中关键的部分:
if ((e as unknown as KeyboardEvent).isComposing) {
return
}
通过检测 isComposing
属性,我们可以知道当前是否处于输入法的组合状态,如果是则不执行发送操作。
2. 使用 Composition 事件监听
更完整的解决方案是同时监听组合事件,使用一个状态变量来跟踪当前是否处于组合输入状态:
import React, { useRef, useEffect } from 'react';
function ChatInput({ onSend }) {
const [message, setMessage] = React.useState('');
const isComposing = useRef(false);
const handleCompositionStart = () => {
isComposing.current = true;
};
const handleCompositionEnd = () => {
isComposing.current = false;
};
const handleKeyDown = (e) => {
if (e.key === 'Enter' && !e.shiftKey && !isComposing.current) {
e.preventDefault();
onSend(message);
setMessage('');
}
};
return (
<textarea
value={message}
onChange={(e) => setMessage(e.target.value)}
onKeyDown={handleKeyDown}
onCompositionStart={handleCompositionStart}
onCompositionEnd={handleCompositionEnd}
placeholder="输入消息..."
/>
);
}
这种方法更可靠,因为它直接监听了输入法的组合事件,能够准确地知道当前是否处于组合输入状态。
3. 使用第三方库
如果你不想自己处理这些复杂的逻辑,也可以使用一些第三方库,比如:
这些库封装了组合事件的处理,使得开发者可以更方便地处理中文输入法的问题。
兼容性测试
在不同的操作系统和浏览器中,输入法的行为可能会有所不同,所以我们需要进行全面的测试:
操作系统 | 浏览器 | 是否存在问题 | 解决方案是否有效 |
---|---|---|---|
Windows | Chrome | 是 | 是 |
Windows | Edge | 是 | 是 |
Windows | Firefox | 是 | 是 |
macOS | Chrome | 是 | 是 |
macOS | Safari | 是 | 是 |
macOS | Firefox | 是 | 是 |
iOS | Safari | 是 | 是 |
Android | Chrome | 是 | 是 |
总结
处理输入框中文输入法问题是开发多语言应用时常见的挑战。通过理解浏览器的组合输入事件机制,我们可以采取适当的措施来避免用户体验问题:
- 检查键盘事件的
isComposing
属性 - 监听
compositionstart
和compositionend
事件 - 使用专门的第三方库来处理这些问题
这些方法可以确保当用户使用中文输入法时,不会因为按下回车键确认文字而意外发送消息,从而提升用户体验。
对应代码:
https://codesandbox.io/p/sandbox/rnz45l?file=%2Fsrc%2FApp.tsx%3A30%2C8