@@ -700,92 +700,125 @@ <h2>查碼練習</h2>
700700 }
701701
702702 if ( isEnglishMode ) {
703- handleEnglishInput ( code ) ;
703+ // Pass event.key to handleEnglishInput
704+ const char = event . key ;
705+ if ( char ) {
706+ handleEnglishInput ( char ) ;
707+ } else {
708+ // Fallback for function keys without a single character
709+ handleEnglishInput ( code ) ;
710+ }
704711 } else {
705- handleChineseInput ( code ) ;
712+ // Pass event.key to handleChineseInput
713+ const char = event . key ;
714+ if ( char ) {
715+ handleChineseInput ( char ) ;
716+ } else {
717+ handleChineseInput ( code ) ;
718+ }
706719 }
707720 } ) ;
708721
709722 // --- 處理中文模式輸入的核心函數 ---
710- function handleChineseInput ( code ) {
711- // 統一處理數字鍵邏輯
712- if ( code . match ( / ^ [ 1 - 9 0 ] $ / ) ) {
713- if ( currentCandidates . length > 0 ) {
714- const num = code === '0' ? 10 : parseInt ( code , 10 ) ;
715- selectCandidate ( num - 1 ) ;
716- } else {
717- insertTextAtCursor ( textOutput , code ) ;
718- }
719- return ;
720- }
721-
722- if ( code === 'backspace' ) {
723+ function handleChineseInput ( char ) {
724+ const isCodeKey = char . match ( / ^ [ a - z A - Z ; ' . / , ] $ / ) || char . match ( / ^ [ 0 - 9 ] $ / ) ;
725+
726+ // 處理刪除、換行、清空等功能鍵
727+ if ( char === 'Backspace' || char === 'backspace' ) {
723728 if ( currentCode . length > 0 ) {
724729 currentCode = currentCode . slice ( 0 , - 1 ) ;
725730 updateStateAndDisplay ( ) ;
726731 } else {
727732 deleteTextAtCursor ( textOutput ) ;
728- updatePhraseLookup ( ) ; // 在刪除 text-output 的文字後更新比對
733+ updatePhraseLookup ( ) ;
729734 }
730735 return ;
731736 }
732- if ( code === 'enter' ) {
737+ if ( char === 'Enter' || char === 'enter' ) {
733738 insertTextAtCursor ( textOutput , '\n' ) ;
734- updatePhraseLookup ( ) ; // 在換行後更新比對
739+ updatePhraseLookup ( ) ;
735740 return ;
736741 }
737- if ( code === 'escape' ) {
742+ if ( char === 'Escape' || char === 'escape' ) {
738743 resetInputState ( ) ;
739744 updatePhraseLookup ( ) ;
740745 return ;
741746 }
742-
743- if ( code === ' ' ) {
747+
748+ // 處理數字鍵選字
749+ if ( char . match ( / ^ [ 0 - 9 ] $ / ) ) {
750+ if ( currentCode . length > 0 ) {
751+ const num = char === '0' ? 10 : parseInt ( char , 10 ) ;
752+ selectCandidate ( num - 1 ) ;
753+ } else {
754+ // 如果沒有編碼輸入,直接插入數字
755+ insertTextAtCursor ( textOutput , char ) ;
756+ updatePhraseLookup ( ) ;
757+ }
758+ return ;
759+ }
760+
761+ // 處理空白鍵選字
762+ if ( char === ' ' || char === 'Space' ) {
744763 if ( currentCandidates . length > 0 ) {
745764 selectCandidate ( 0 ) ;
746765 } else {
747766 insertTextAtCursor ( textOutput , ' ' ) ;
748- updatePhraseLookup ( ) ; // 在空格後更新比對
767+ updatePhraseLookup ( ) ;
749768 }
750769 return ;
751770 }
752-
753- const inputChar = code . toLowerCase ( ) ;
754- if ( inputChar . match ( / ^ [ a - z ; ' . / , ] $ / ) ) {
755- if ( currentCode . length === MAX_CODE_LENGTH && currentCandidates . length > 0 ) {
756- selectCandidate ( 0 ) ;
757- currentCode = inputChar ;
771+
772+ // 處理正常的編碼輸入
773+ if ( isCodeKey ) {
774+ const lowerChar = char . toLowerCase ( ) ;
775+ if ( currentCode . length < MAX_CODE_LENGTH ) {
776+ currentCode += lowerChar ;
758777 } else {
759- currentCode += inputChar ;
778+ // 如果已達最大長度,先選字再輸入新編碼
779+ if ( currentCandidates . length > 0 ) {
780+ selectCandidate ( 0 ) ;
781+ }
782+ currentCode = lowerChar ;
760783 }
761784 updateStateAndDisplay ( ) ;
785+ } else {
786+ // 處理所有其他非編碼字元(如標點符號、特殊符號等)
787+ if ( currentCode . length > 0 ) {
788+ if ( currentCandidates . length > 0 ) {
789+ selectCandidate ( 0 ) ;
790+ }
791+ resetInputState ( ) ;
792+ }
793+ insertTextAtCursor ( textOutput , char ) ;
794+ updatePhraseLookup ( ) ;
762795 }
763796 }
764797
765798 // --- 處理英文模式輸入的新函數 ---
766799 function handleEnglishInput ( char ) {
767800 // 處理功能鍵
768- if ( char === 'backspace' ) {
801+ if ( char === 'Backspace' || char === ' backspace') {
769802 deleteTextAtCursor ( textOutput ) ;
770803 updatePhraseLookup ( ) ;
771804 return ;
772805 }
773- if ( char === 'enter' ) {
806+ if ( char === 'Enter' || char === ' enter') {
774807 insertTextAtCursor ( textOutput , '\n' ) ;
775808 updatePhraseLookup ( ) ;
776809 return ;
777810 }
778- if ( char === 'escape' ) {
811+ if ( char === 'Escape' || char === ' escape') {
779812 resetInputState ( ) ;
780813 updatePhraseLookup ( ) ;
781814 return ;
782815 }
783- if ( char === ' ' ) {
816+ if ( char === ' ' || char === 'Space' ) {
784817 insertTextAtCursor ( textOutput , ' ' ) ;
785818 updatePhraseLookup ( ) ;
786819 return ;
787820 }
788-
821+
789822 // 處理英文字母和數字、符號
790823 if ( char . length === 1 ) {
791824 insertTextAtCursor ( textOutput , char ) ;
@@ -974,36 +1007,23 @@ <h2>查碼練習</h2>
9741007
9751008 // 在中文模式下,處理長按 Shift 後的符號鍵
9761009 if ( ! isEnglishMode && event . shiftKey ) {
977- const code = getKeyCode ( event ) ;
978- const outputChar = keyname_map_chinese_shifted [ code ] ;
1010+ const char = event . key ;
1011+ const outputChar = keyname_map_chinese_shifted [ char ] ;
9791012 if ( outputChar ) {
9801013 event . preventDefault ( ) ;
9811014 insertTextAtCursor ( textOutput , outputChar ) ;
9821015 return ;
9831016 }
9841017 }
9851018
986- // 處理實體鍵盤的刪除鍵
987- if ( event . key === 'Backspace' ) {
988- if ( currentCode . length > 0 ) {
989- event . preventDefault ( ) ;
990- currentCode = currentCode . slice ( 0 , - 1 ) ;
991- updateStateAndDisplay ( ) ;
992- } else {
993- return ; // 允許瀏覽器預設的刪除行為
994- }
1019+ if ( isEnglishMode ) {
1020+ // 英文模式直接處理 event.key
1021+ handleEnglishInput ( event . key ) ;
1022+ } else {
1023+ // 中文模式直接處理 event.key
1024+ handleChineseInput ( event . key ) ;
9951025 }
9961026
997- // 處理一般輸入
998- const code = getKeyCode ( event ) ;
999- if ( code && code !== 'shift' ) {
1000- event . preventDefault ( ) ;
1001- if ( isEnglishMode ) {
1002- handleEnglishInput ( event . key ) ;
1003- } else {
1004- handleChineseInput ( code ) ;
1005- }
1006- }
10071027 } ) ;
10081028
10091029 // keyup 事件處理
@@ -1094,34 +1114,36 @@ <h2>查碼練習</h2>
10941114 }
10951115 }
10961116
1097- for ( let j = 0 ; j < 5 ; j ++ ) {
1098- const codeLabel = document . createElement ( 'span' ) ;
1099- codeLabel . className = 'code-label' ;
1100-
1101- if ( j < codesToDisplay . length ) {
1102- const result = codesToDisplay [ j ] ;
1103- const code = result . code ;
1104- const candidatesForCode = currentCodemap [ code ] ;
1117+ if ( codesToDisplay . length > 0 ) {
1118+ for ( let j = 0 ; j < 5 ; j ++ ) {
1119+ const codeLabel = document . createElement ( 'span' ) ;
1120+ codeLabel . className = 'code-label' ;
11051121
1106- let suffix = '' ;
1107- if ( candidatesForCode && candidatesForCode . length > 1 ) {
1108- if ( result . index === 0 ) {
1109- suffix = '' ;
1110- } else if ( result . index < 9 ) {
1111- const digit = ( result . index + 1 ) . toString ( ) ;
1112- suffix = fullWidthDigits [ digit ] ;
1113- } else if ( result . index === 9 ) {
1114- suffix = '0' ;
1115- } else {
1116- suffix = '>' ;
1122+ if ( j < codesToDisplay . length ) {
1123+ const result = codesToDisplay [ j ] ;
1124+ const code = result . code ;
1125+ const candidatesForCode = currentCodemap [ code ] ;
1126+
1127+ let suffix = '' ;
1128+ if ( candidatesForCode && candidatesForCode . length > 1 ) {
1129+ if ( result . index === 0 ) {
1130+ suffix = '' ;
1131+ } else if ( result . index < 9 ) {
1132+ const digit = ( result . index + 1 ) . toString ( ) ;
1133+ suffix = fullWidthDigits [ digit ] ;
1134+ } else if ( result . index === 9 ) {
1135+ suffix = '0' ;
1136+ } else {
1137+ suffix = '>' ;
1138+ }
11171139 }
1140+
1141+ codeLabel . textContent = formatCode ( code ) + suffix ;
1142+ } else {
1143+ codeLabel . textContent = '' ;
11181144 }
1119-
1120- codeLabel . textContent = formatCode ( code ) + suffix ;
1121- } else {
1122- codeLabel . textContent = '' ;
1145+ encodingContainer . appendChild ( codeLabel ) ;
11231146 }
1124- encodingContainer . appendChild ( codeLabel ) ;
11251147 }
11261148
11271149 column . appendChild ( charLabel ) ;
0 commit comments