215215 background-color : var (--primary-color );
216216 color : white;
217217 }
218+
219+ # status-message {
220+ margin-top : 10px ;
221+ font-size : 0.9em ;
222+ color : # d32f2f ;
223+ font-weight : bold;
224+ }
218225 </ style >
219226</ head >
220227< body >
221228 < div class ="container ">
222229 < h1 > 三碼中文輸入法模擬器</ h1 >
230+ < p id ="status-message "> </ p >
223231 < div class ="input-area ">
224232 < textarea id ="output " placeholder ="點擊下方鍵盤或輸入英數字... "> </ textarea >
225233 < div id ="candidate-area " class ="candidate-area "> </ div >
@@ -250,13 +258,13 @@ <h3>反向查詢 (輸入單一中文字)</h3>
250258 let currentCodemap = { } ;
251259 let currentReverseCodemap = { } ;
252260 let isEnglishMode = false ;
253- let shiftTimer = null ;
254261 const output = document . getElementById ( 'output' ) ;
255262 const candidateArea = document . getElementById ( 'candidate-area' ) ;
256263 const keyboard = document . getElementById ( 'keyboard' ) ;
257264 const searchInput = document . getElementById ( 'searchInput' ) ;
258265 const searchResult = document . getElementById ( 'searchResult' ) ;
259266 const modeDisplay = document . getElementById ( 'mode-display' ) ;
267+ const statusMessage = document . getElementById ( 'status-message' ) ;
260268
261269 // --- 載入碼表檔案 ---
262270 async function loadCodemap ( filePath ) {
@@ -269,6 +277,7 @@ <h3>反向查詢 (輸入單一中文字)</h3>
269277 return parseCinFile ( text ) ;
270278 } catch ( error ) {
271279 console . error ( error ) ;
280+ statusMessage . textContent = `載入碼表檔案失敗:無法找到 ${ filePath } 。請確認所有檔案都在同一目錄下。` ;
272281 return { forward : { } , reverse : { } } ;
273282 }
274283 }
@@ -445,15 +454,27 @@ <h3>反向查詢 (輸入單一中文字)</h3>
445454
446455 document . addEventListener ( 'keydown' , ( event ) => {
447456 const key = event . key . toLowerCase ( ) ;
448- const keys = 'abcdefghijklmnopqrstuvwxyz;,.' ;
457+ const keys = "abcdefghijklmnopqrstuvwxyz;,." ;
458+
459+ // 使用 Shift 鍵切換模式
460+ if ( event . key === "Shift" ) {
461+ isEnglishMode = ! isEnglishMode ;
462+ updateModeDisplay ( ) ;
463+ updateKeyboardDisplay ( ) ;
464+ resetInputState ( ) ;
465+ event . preventDefault ( ) ; // 避免 Shift 鍵的預設行為
466+ return ;
467+ }
449468
469+ // 在英數模式下直接輸出
450470 if ( isEnglishMode ) {
451- if ( keys . includes ( key ) || key === '/' ) {
452- output . value += event . key ;
471+ if ( keys . includes ( key ) || key === '/' || key === ' ' || event . key === 'Backspace' || event . key . length === 1 ) {
472+ output . value += event . key ;
453473 }
454474 return ;
455475 }
456476
477+ // 中文模式邏輯
457478 if ( keys . includes ( key ) ) {
458479 if ( currentCode . length < 3 ) {
459480 currentCode += key ;
@@ -469,6 +490,7 @@ <h3>反向查詢 (輸入單一中文字)</h3>
469490 } else if ( output . value . length > 0 ) {
470491 output . value = output . value . slice ( 0 , - 1 ) ;
471492 }
493+ event . preventDefault ( ) ;
472494 } else if ( event . key === ' ' ) {
473495 if ( currentCandidates . length > 0 ) {
474496 output . value += currentCandidates [ 0 ] ;
@@ -483,29 +505,8 @@ <h3>反向查詢 (輸入單一中文字)</h3>
483505 output . value += currentCandidates [ index ] ;
484506 resetInputState ( ) ;
485507 }
486- } else if ( event . key === 'Shift' ) {
487- if ( ! shiftTimer ) {
488- shiftTimer = setTimeout ( ( ) => {
489- isEnglishMode = ! isEnglishMode ;
490- updateModeDisplay ( ) ;
491- updateKeyboardDisplay ( ) ;
492- resetInputState ( ) ;
493- shiftTimer = null ;
494- } , 300 ) ;
495- }
496- } else {
497- if ( currentCandidates . length === 0 ) {
498- output . value += event . key ;
499- }
500- }
501- } ) ;
502-
503- document . addEventListener ( 'keyup' , ( event ) => {
504- if ( event . key === 'Shift' ) {
505- if ( shiftTimer ) {
506- clearTimeout ( shiftTimer ) ;
507- shiftTimer = null ;
508- }
508+ } else if ( event . key . length === 1 ) {
509+ output . value += event . key ;
509510 }
510511 } ) ;
511512
0 commit comments