Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
Tags
- whisper-1
- 자바스크립트sort함수
- 이터레이션프로토콜
- flex특징
- AI
- flexgrid차이점
- 바닐라JS #바닐라JS로크롭앱만들기 #
- 자바스크립트문법 #노마드코더 #
- 자바객체 #자바인스턴스 #객체와인스턴스차이점
- javascript문법
- 배열재정렬함수
- ime일본어처리
- ES6란
- 자바스크립트filter
- interable
- Realtime
- tts-1
- gpt-4o-transcribe
- DestructuringAssignment
- JAVA #Swing #자바스윙 #스윙
- iterationprotocol
- ime란
- chatGPT
- 음성채팅
- flex사용법
- 이터러블프로토콜
- realtimeapi
- 이터레이터프로토콜
- OpenAI
- 레이아웃모델
Archives
- Today
- Total
끄적끄적 개발기록
IME과 textarea enter처리 본문
enter를 치면 input창이 클릭되도록 하는 함수를 만들었다.
keyup될 때 구현했는데 영어는 괜찮은데 자꾸 한글이 씹하는(?) 현상이 발생했다.
const handleKeyUp = (e: KeyboardEvent<HTMLTextAreaElement>) => {
if (textareaRef.current) {
const maxHeight = 4 * 22; // 최대 4줄, 줄당 22px
if (e.key === 'Enter') {
e.preventDefault();
if (e.ctrlKey) {
if (textareaRef.current.scrollHeight < maxHeight) {
const start = textareaRef.current.selectionStart;
const end = textareaRef.current.selectionEnd;
const value = textareaRef.current.value;
const newValue = value.substring(0, start) + '\n' + value.substring(end);
setContent(newValue);
textareaRef.current.selectionStart = textareaRef.current.selectionEnd = start + 1;
}
} else {
handleSendMessageButton();
}
}
}
};
<button
className={bot-btn-send ${isOpenBottomMenu ? 'active' : ''}}
onClick={handleSendMessageButton}>
<IoSend className="send-svg" />
</button>
알고보니 버튼이 두번 클릭되는 문제였다.
그럼 왜 영어는 괜찮은데 한글은 두번 클릭되는 현상이 발생할까?
바로 IME(입력기)가 작동하는 방식과 관련이 있다는 것!!
IME란 Input Method Editor로, 사용자가 여러 개의 키 입력을 통해 문자를 입력할 수 있도록 도와주는 소프트웨어이다.
이는 특히 한글, 중국어, 일본어와 같은 언어를 입력할 때 유용! 이러한 언어는 단일 키 입력으로 완전한 문자를 표현할 수 없으므로, IME는 여러 키 입력을 조합하여 최종 문자를 생성할 수 있다.
영어 입력의 경우, 각 키 입력이 즉시 처리되지만, 한국어 입력의 경우 IME가 여러 키 입력을 조합하여 하나의 글자를 완성한다. 이 과정에서 이벤트가 여러 번 발생할 수 있으며, 특히 조합이 완료되지 않은 상태에서 Enter 키를 누르면 onKeyDown과 onKeyUp 이벤트가 예상치 않게 처리될 수 있다는 것!
이에 대한 해결책으로
onCompositionStart와 onCompositionEnd를 사용하여 IME 입력이 시작하는 시점 끝나는 시점을 보고 끝났을 때만 handleSendMessageButton함수가 실행되게 변경해주었다.
const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {
const platform = getPlatform();
const isCtrlOrCmd = platform === 'Mac' ? e.metaKey : e.ctrlKey;
if (textareaRef.current) {
if (e.key === 'Enter' && !isComposing) {
if (isCtrlOrCmd) {
const maxHeight = 4 * 22; // 최대 4줄, 줄당 22px
if (textareaRef.current.scrollHeight < maxHeight) {
const start = textareaRef.current.selectionStart;
const end = textareaRef.current.selectionEnd;
const value = textareaRef.current.value;
const newValue = value.substring(0, start) + '\n' + value.substring(end);
setContent(newValue);
textareaRef.current.selectionStart = textareaRef.current.selectionEnd = start + 1;
}
} else {
e.preventDefault();
handleSendMessageButton();
}
}
}
};
const handleCompositionStart = () => {
setIsComposing(true);
};
const handleCompositionEnd = () => {
setIsComposing(false);
};
<textarea
ref={textareaRef}
className="bot-textarea"
onChange={handleInputChange}
onKeyDown={handleKeyDown}
onCompositionStart={handleCompositionStart}
onCompositionEnd={handleCompositionEnd}
value={content}
placeholder="Send a message.."
rows={1}
onInput={adjustTextareaHeight}
/>
아주 잘 동작하는 것을 확인해볼 수 있었다!
'개발 > Problem&Solution' 카테고리의 다른 글
| 로컬state를 만들어 서버 부하 줄이기 (0) | 2024.07.17 |
|---|---|
| Typescript 인덱싱 에러 (0) | 2024.07.15 |
| react-query, retetchOnWindowFocus (0) | 2024.06.26 |
| react 버그 해결 (1) | 2024.06.10 |
| react hook의 호출 규칙 (0) | 2024.05.08 |