@@ -307,9 +307,9 @@ <h2>檔案下載區:</h2>
307307 < ul >
308308 < li > < a href ="3code.pdf " download ="" target ="_blank "> 輸入法說明檔</ a > </ li >
309309 < li > < a href ="3code.zip " download ="" target ="_blank "> 輸入法壓縮檔</ a > </ li >
310- < li > < a href ="3code .txt " download ="" target ="_blank "> 常用字碼檔</ a > </ li >
311- < li > < a href ="3code2 .txt " download ="" target ="_blank "> 次常用字碼檔</ a > </ li >
312- < li > < a href ="3code .cin " download ="" target ="_blank "> CIN字碼檔</ a > </ li >
310+ < li > < a href ="3codes .txt " download ="" target ="_blank "> 常用字碼檔</ a > </ li >
311+ < li > < a href ="3codes2 .txt " download ="" target ="_blank "> 次常用字碼檔</ a > </ li >
312+ < li > < a href ="3codes .cin " download ="" target ="_blank "> CIN字碼檔</ a > </ li >
313313 </ ul >
314314 </ div >
315315 < div class ="mode-switcher ">
@@ -325,7 +325,7 @@ <h2>輸入法模式:</h2>
325325 </ div >
326326 </ div >
327327
328- < div class ="text-output-area " id ="text-output "> </ div >
328+ < textarea class ="text-output-area " id ="text-output "> </ textarea >
329329
330330 < div class ="input-area ">
331331 < input type ="text " id ="main-input " placeholder ="編碼顯示在此 " readonly ="">
@@ -519,6 +519,27 @@ <h2>輸入法模式:</h2>
519519 } ) ;
520520 } ) ;
521521
522+ // 函式:在游標位置插入文字
523+ function insertTextAtCursor ( element , text ) {
524+ const start = element . selectionStart ;
525+ const end = element . selectionEnd ;
526+ element . value = element . value . substring ( 0 , start ) + text + element . value . substring ( end ) ;
527+ element . selectionStart = element . selectionEnd = start + text . length ;
528+ element . focus ( ) ;
529+ }
530+
531+ // 函式:在游標位置刪除文字
532+ function deleteTextAtCursor ( element ) {
533+ const start = element . selectionStart ;
534+ if ( start > 0 ) {
535+ const end = element . selectionEnd ;
536+ let text = element . value ;
537+ element . value = text . substring ( 0 , start - 1 ) + text . substring ( end ) ;
538+ element . selectionStart = element . selectionEnd = start - 1 ;
539+ element . focus ( ) ;
540+ }
541+ }
542+
522543 // --- 虛擬鍵盤點擊事件 ---
523544 keyboardContainer . addEventListener ( 'click' , ( event ) => {
524545 const key = event . target . closest ( '.key' ) ;
@@ -551,7 +572,7 @@ <h2>輸入法模式:</h2>
551572 const num = code === '0' ? 10 : parseInt ( code , 10 ) ;
552573 selectCandidate ( num - 1 ) ;
553574 } else {
554- textOutput . textContent += code ;
575+ insertTextAtCursor ( textOutput , code ) ;
555576 }
556577 return ;
557578 }
@@ -560,13 +581,13 @@ <h2>輸入法模式:</h2>
560581 if ( currentCode . length > 0 ) {
561582 currentCode = currentCode . slice ( 0 , - 1 ) ;
562583 updateStateAndDisplay ( ) ;
563- } else if ( textOutput . textContent . length > 0 ) {
564- textOutput . textContent = textOutput . textContent . slice ( 0 , - 1 ) ;
584+ } else {
585+ deleteTextAtCursor ( textOutput ) ;
565586 }
566587 return ;
567588 }
568589 if ( code === 'enter' ) {
569- textOutput . textContent += '\n' ;
590+ insertTextAtCursor ( textOutput , '\n' ) ;
570591 return ;
571592 }
572593 if ( code === 'escape' ) {
@@ -588,7 +609,7 @@ <h2>輸入法模式:</h2>
588609 if ( currentCandidates . length > 0 ) {
589610 selectCandidate ( 0 ) ;
590611 } else {
591- textOutput . textContent += ' ' ;
612+ insertTextAtCursor ( textOutput , ' ' ) ;
592613 }
593614 return ;
594615 }
@@ -609,27 +630,25 @@ <h2>輸入法模式:</h2>
609630 function handleEnglishInput ( char ) {
610631 // 處理功能鍵
611632 if ( char === 'backspace' ) {
612- if ( textOutput . textContent . length > 0 ) {
613- textOutput . textContent = textOutput . textContent . slice ( 0 , - 1 ) ;
614- }
633+ deleteTextAtCursor ( textOutput ) ;
615634 return ;
616635 }
617636 if ( char === 'enter' ) {
618- textOutput . textContent += '\n' ;
637+ insertTextAtCursor ( textOutput , '\n' ) ;
619638 return ;
620639 }
621640 if ( char === 'escape' ) {
622641 resetInputState ( ) ;
623642 return ;
624643 }
625644 if ( char === ' ' ) {
626- textOutput . textContent += ' ' ;
645+ insertTextAtCursor ( textOutput , ' ' ) ;
627646 return ;
628647 }
629648
630649 // 處理英文字母和數字、符號
631650 if ( char . length === 1 ) {
632- textOutput . textContent += char ;
651+ insertTextAtCursor ( textOutput , char ) ;
633652 }
634653 }
635654
@@ -657,7 +676,7 @@ <h2>輸入法模式:</h2>
657676
658677 if ( currentCode . length === MAX_CODE_LENGTH ) {
659678 if ( currentCandidates . length === 1 ) {
660- textOutput . textContent += currentCandidates [ 0 ] ;
679+ insertTextAtCursor ( textOutput , currentCandidates [ 0 ] ) ;
661680 resetInputState ( ) ;
662681 return ;
663682 } else if ( currentCandidates . length === 0 ) {
@@ -699,7 +718,7 @@ <h2>輸入法模式:</h2>
699718 function selectCandidate ( index ) {
700719 const selectedCandidate = currentCandidates [ currentPage * candidatesPerPage + index ] ;
701720 if ( selectedCandidate ) {
702- textOutput . textContent += selectedCandidate ;
721+ insertTextAtCursor ( textOutput , selectedCandidate ) ;
703722 resetInputState ( ) ;
704723 }
705724 }
@@ -862,4 +881,4 @@ <h2>輸入法模式:</h2>
862881 switchInputMethod ( 'primary' ) ;
863882 updateKeyboardDisplay ( ) ;
864883 </ script >
865- </ body > </ html >
884+ </ body > </ html >
0 commit comments