Skip to content

Commit 59d7ca3

Browse files
authored
Add files via upload
1 parent 0427f3f commit 59d7ca3

1 file changed

Lines changed: 63 additions & 97 deletions

File tree

test.html

Lines changed: 63 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,8 @@ <h2>查碼練習</h2>
479479
let currentCodemap = {};
480480
let currentReverseCodemap = {};
481481

482+
const codeKeys = "abcdefghijklmnopqrstuvwxyz;'./,";
483+
482484
const keyname_map_upper = {
483485
'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D', 'e': 'E', 'f': 'F', 'g': 'G',
484486
'h': 'H', 'i': 'I', 'j': 'J', 'k': 'K', 'l': 'L', 'm': 'M', 'n': 'N',
@@ -498,7 +500,6 @@ <h2>查碼練習</h2>
498500
'shift': 'Shift', 'enter': 'Enter', 'backspace': '刪除鍵',
499501
};
500502

501-
// 中文模式下,長按 Shift 顯示的對應字元(全數改為半形)
502503
const keyname_map_chinese_shifted = {
503504
'1': '!', '2': '@', '3': '#', '4': '$', '5': '%', '6': '^', '7': '&', '8': '*', '9': '(', '0': ')',
504505
'q': 'Q', 'w': 'W', 'e': 'E', 'r': 'R', 't': 'T', 'y': 'Y', 'u': 'U', 'i': 'I', 'o': 'O', 'p': 'P',
@@ -508,7 +509,6 @@ <h2>查碼練習</h2>
508509
',': '<', '.': '>', '/': '?',
509510
};
510511

511-
// 英文模式下,長按 Shift 顯示的對應字元(全數改為半形)
512512
const keyname_map_english_shifted = {
513513
'1': '!', '2': '@', '3': '#', '4': '$', '5': '%', '6': '^', '7': '&', '8': '*', '9': '(', '0': ')',
514514
'q': 'Q', 'w': 'W', 'e': 'E', 'r': 'R', 't': 'T', 'y': 'Y', 'u': 'U', 'i': 'I', 'o': 'O', 'p': 'P',
@@ -615,11 +615,9 @@ <h2>查碼練習</h2>
615615
}
616616
resetInputState();
617617
updateModeDisplay();
618-
// 重新載入碼表後,更新查碼練習區
619618
updatePhraseLookup();
620619
}
621620

622-
// 模式切換單選鈕事件監聽
623621
modeRadioButtons.forEach(radio => {
624622
radio.addEventListener('change', (event) => {
625623
switchInputMethod(event.target.value);
@@ -646,23 +644,8 @@ <h2>查碼練習</h2>
646644
element.focus();
647645
}
648646
}
649-
650-
// --- 處理長按 Shift 虛擬鍵盤點擊的輔助函數 ---
651-
function handleShiftedVirtualInput(code) {
652-
let outputChar = '';
653-
if (isEnglishMode) {
654-
outputChar = keyname_map_english_shifted[code];
655-
} else {
656-
outputChar = keyname_map_chinese_shifted[code];
657-
}
658-
if (outputChar) {
659-
insertTextAtCursor(textOutput, outputChar);
660-
return true;
661-
}
662-
return false;
663-
}
664647

665-
// --- 虛擬鍵盤點擊事件 ---
648+
// --- 虛擬鍵盤點擊事件處理 ---
666649
keyboardContainer.addEventListener('click', (event) => {
667650
const key = event.target.closest('.key');
668651
if (!key) return;
@@ -681,50 +664,51 @@ <h2>查碼練習</h2>
681664
return;
682665
}
683666

667+
// 處理長按Shift模式下的輸入
684668
if (isLongPressActive) {
685-
if (handleShiftedVirtualInput(code)) {
669+
let outputChar = isEnglishMode ? keyname_map_english_shifted[code] : keyname_map_chinese_shifted[code];
670+
if (outputChar) {
671+
insertTextAtCursor(textOutput, outputChar);
672+
resetInputState(); // 長按Shift後輸入應該清空編碼
673+
updatePhraseLookup();
686674
return;
687675
}
688676
}
677+
678+
// 處理一般點擊輸入
679+
const char = keyname_map_lower[code];
680+
if (char) {
681+
processInput(char);
682+
}
689683

690684
if (code === '<') {
691685
handlePageChange('previous');
692686
} else if (code === '>') {
693687
handlePageChange('next');
694688
} else if (code === 'backspace') {
695-
deleteTextAtCursor(textOutput);
696-
return;
689+
processInput('backspace');
697690
} else if (code === 'enter') {
698-
insertTextAtCursor(textOutput, '\n');
699-
return;
691+
processInput('enter');
700692
}
701-
693+
});
694+
695+
// --- 統一處理鍵盤輸入的核心函數 ---
696+
function processInput(char) {
702697
if (isEnglishMode) {
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-
}
698+
handleEnglishInput(char);
711699
} else {
712-
// Pass event.key to handleChineseInput
713-
const char = event.key;
714-
if (char) {
715-
handleChineseInput(char);
716-
} else {
717-
handleChineseInput(code);
718-
}
700+
handleChineseInput(char);
719701
}
720-
});
721-
702+
}
703+
704+
function isCodeKey(char) {
705+
return codeKeys.includes(char.toLowerCase());
706+
}
707+
722708
// --- 處理中文模式輸入的核心函數 ---
723709
function handleChineseInput(char) {
724-
const isCodeKey = char.match(/^[a-zA-Z;'./,]$/) || char.match(/^[0-9]$/);
725-
726-
// 處理刪除、換行、清空等功能鍵
727-
if (char === 'Backspace' || char === 'backspace') {
710+
// 處理功能鍵
711+
if (char === 'backspace' || char === 'Backspace') {
728712
if (currentCode.length > 0) {
729713
currentCode = currentCode.slice(0, -1);
730714
updateStateAndDisplay();
@@ -734,31 +718,31 @@ <h2>查碼練習</h2>
734718
}
735719
return;
736720
}
737-
if (char === 'Enter' || char === 'enter') {
721+
if (char === 'enter' || char === 'Enter') {
738722
insertTextAtCursor(textOutput, '\n');
723+
resetInputState();
739724
updatePhraseLookup();
740725
return;
741726
}
742-
if (char === 'Escape' || char === 'escape') {
727+
if (char === 'escape' || char === 'Escape') {
743728
resetInputState();
744729
updatePhraseLookup();
745730
return;
746731
}
747732

748-
// 處理數字鍵選字
733+
// 處理數字鍵選字或直出
749734
if (char.match(/^[0-9]$/)) {
750-
if (currentCode.length > 0) {
735+
if (currentCandidates.length > 0) {
751736
const num = char === '0' ? 10 : parseInt(char, 10);
752737
selectCandidate(num - 1);
753738
} else {
754-
// 如果沒有編碼輸入,直接插入數字
755739
insertTextAtCursor(textOutput, char);
756740
updatePhraseLookup();
757741
}
758742
return;
759743
}
760744

761-
// 處理空白鍵選字
745+
// 處理空白鍵選字或直出
762746
if (char === ' ' || char === 'Space') {
763747
if (currentCandidates.length > 0) {
764748
selectCandidate(0);
@@ -770,45 +754,42 @@ <h2>查碼練習</h2>
770754
}
771755

772756
// 處理正常的編碼輸入
773-
if (isCodeKey) {
774-
const lowerChar = char.toLowerCase();
757+
if (isCodeKey(char)) {
775758
if (currentCode.length < MAX_CODE_LENGTH) {
776-
currentCode += lowerChar;
759+
currentCode += char;
777760
} else {
778761
// 如果已達最大長度,先選字再輸入新編碼
779762
if (currentCandidates.length > 0) {
780763
selectCandidate(0);
781764
}
782-
currentCode = lowerChar;
765+
currentCode = char;
783766
}
784767
updateStateAndDisplay();
785768
} else {
786-
// 處理所有其他非編碼字元(如標點符號、特殊符號等)
769+
// 如果輸入的不是編碼鍵,則直接輸出
787770
if (currentCode.length > 0) {
788771
if (currentCandidates.length > 0) {
789772
selectCandidate(0);
790773
}
791-
resetInputState();
792774
}
793775
insertTextAtCursor(textOutput, char);
794776
updatePhraseLookup();
795777
}
796778
}
797779

798-
// --- 處理英文模式輸入的新函數 ---
780+
// --- 處理英文模式輸入的函數 ---
799781
function handleEnglishInput(char) {
800-
// 處理功能鍵
801-
if (char === 'Backspace' || char === 'backspace') {
782+
if (char === 'backspace' || char === 'Backspace') {
802783
deleteTextAtCursor(textOutput);
803784
updatePhraseLookup();
804785
return;
805786
}
806-
if (char === 'Enter' || char === 'enter') {
787+
if (char === 'enter' || char === 'Enter') {
807788
insertTextAtCursor(textOutput, '\n');
808789
updatePhraseLookup();
809790
return;
810791
}
811-
if (char === 'Escape' || char === 'escape') {
792+
if (char === 'escape' || char === 'Escape') {
812793
resetInputState();
813794
updatePhraseLookup();
814795
return;
@@ -819,7 +800,6 @@ <h2>查碼練習</h2>
819800
return;
820801
}
821802

822-
// 處理英文字母和數字、符號
823803
if (char.length === 1) {
824804
insertTextAtCursor(textOutput, char);
825805
updatePhraseLookup();
@@ -852,7 +832,7 @@ <h2>查碼練習</h2>
852832
if (currentCandidates.length === 1) {
853833
insertTextAtCursor(textOutput, currentCandidates[0]);
854834
resetInputState();
855-
updatePhraseLookup(); // 在自動選字後更新比對
835+
updatePhraseLookup();
856836
return;
857837
} else if (currentCandidates.length === 0) {
858838
resetInputState();
@@ -897,7 +877,7 @@ <h2>查碼練習</h2>
897877
if (selectedCandidate) {
898878
insertTextAtCursor(textOutput, selectedCandidate);
899879
resetInputState();
900-
updatePhraseLookup(); // 在選字後更新比對
880+
updatePhraseLookup();
901881
}
902882
}
903883

@@ -940,7 +920,6 @@ <h2>查碼練習</h2>
940920
}
941921

942922
// --- 實體鍵盤事件處理 ---
943-
// 取得按鍵代碼的輔助函數,使用 event.code 來確保物理鍵的一致性
944923
function getKeyCode(event) {
945924
const code = event.code;
946925
if (code.startsWith('Key')) {
@@ -965,9 +944,7 @@ <h2>查碼練習</h2>
965944
}
966945
}
967946

968-
// keydown 事件處理
969947
document.addEventListener('keydown', (event) => {
970-
// 允許 Ctrl/Meta 鍵組合使用
971948
if (event.ctrlKey || event.metaKey) {
972949
return;
973950
}
@@ -980,19 +957,6 @@ <h2>查碼練習</h2>
980957
}
981958
}
982959

983-
// 處理 Shift + < 或 Shift + > 的翻頁功能
984-
if (event.shiftKey && (event.key === '<' || event.key === '>')) {
985-
if (!isEnglishMode && currentCandidates.length > candidatesPerPage) {
986-
event.preventDefault();
987-
if (event.key === '<') {
988-
handlePageChange('previous');
989-
} else if (event.key === '>') {
990-
handlePageChange('next');
991-
}
992-
return;
993-
}
994-
}
995-
996960
if (event.key === 'Shift') {
997961
if (!isShiftDown) {
998962
isShiftDown = true;
@@ -1005,28 +969,35 @@ <h2>查碼練習</h2>
1005969
return;
1006970
}
1007971

1008-
// 在中文模式下,處理長按 Shift 後的符號鍵
1009-
if (!isEnglishMode && event.shiftKey) {
972+
if (isLongPressActive && event.shiftKey) {
1010973
const char = event.key;
1011-
const outputChar = keyname_map_chinese_shifted[char];
974+
const outputChar = isEnglishMode ? keyname_map_english_shifted[char] : keyname_map_chinese_shifted[char];
1012975
if (outputChar) {
1013976
event.preventDefault();
1014977
insertTextAtCursor(textOutput, outputChar);
978+
resetInputState(); // 長按Shift後輸入應該清空編碼
979+
updatePhraseLookup();
1015980
return;
1016981
}
1017982
}
1018983

984+
const char = event.key;
1019985
if (isEnglishMode) {
1020-
// 英文模式直接處理 event.key
1021-
handleEnglishInput(event.key);
986+
if (!event.altKey && !event.ctrlKey) {
987+
event.preventDefault();
988+
handleEnglishInput(char);
989+
}
1022990
} else {
1023-
// 中文模式直接處理 event.key
1024-
handleChineseInput(event.key);
991+
if (!event.altKey && !event.ctrlKey) {
992+
const isInputKey = isCodeKey(char) || char.match(/^[0-9]$/) || char === ' ' || char === 'Enter' || char === 'Backspace' || char === 'Escape' || char === '<' || char === '>';
993+
if (isInputKey) {
994+
event.preventDefault();
995+
handleChineseInput(char);
996+
}
997+
}
1025998
}
1026-
1027999
});
10281000

1029-
// keyup 事件處理
10301001
document.addEventListener('keyup', (event) => {
10311002
const virtualKeyCode = getKeyCode(event);
10321003
if (virtualKeyCode) {
@@ -1060,7 +1031,6 @@ <h2>查碼練習</h2>
10601031
const textToCompare = textOutput.value;
10611032
encodingResults.innerHTML = '';
10621033

1063-
// 計算連續正確字元的數量
10641034
let correctCharsCount = 0;
10651035
for (let i = 0; i < textToCompare.length && i < textToSearch.length; i++) {
10661036
if (textToCompare[i] === textToSearch[i]) {
@@ -1070,19 +1040,16 @@ <h2>查碼練習</h2>
10701040
}
10711041
}
10721042

1073-
// 根據正確字數計算查碼區塊的起始索引
10741043
const lookupStartIndex = Math.floor(correctCharsCount / 10) * 10;
10751044
const characters = textToSearch.split('').slice(lookupStartIndex, lookupStartIndex + 10);
10761045

1077-
// 固定顯示10個欄位
10781046
for (let i = 0; i < 10; i++) {
10791047
const column = document.createElement('div');
10801048
column.className = 'char-encoding-column';
10811049

10821050
const charLabel = document.createElement('span');
10831051
charLabel.className = 'char-label';
10841052

1085-
// 判斷字元是否比對正確,並設定對應的顏色
10861053
if (i < characters.length) {
10871054
const char = characters[i];
10881055
charLabel.textContent = char;
@@ -1095,7 +1062,6 @@ <h2>查碼練習</h2>
10951062
charLabel.classList.add('incorrect-char');
10961063
}
10971064
} else {
1098-
// 如果 text-output 比較短,則未輸入的字元顯示為紅色
10991065
charLabel.classList.add('incorrect-char');
11001066
}
11011067
}

0 commit comments

Comments
 (0)