Skip to content

Commit eb13ef5

Browse files
authored
Update test.html
1 parent 44a2093 commit eb13ef5

1 file changed

Lines changed: 103 additions & 146 deletions

File tree

test.html

Lines changed: 103 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -400,25 +400,24 @@ <h2>輸入法模式:</h2>
400400
</div>
401401
</div>
402402
<script>
403-
// --- 資料處理與解析 ---
403+
// --- 核心變數與元素 ---
404+
let currentCode = '';
405+
let currentCandidates = [];
404406
let primaryCodemap = {};
405407
let secondaryCodemap = {};
406408
let currentCodemap = {};
407409
let currentReverseCodemap = {};
408-
let currentCode = '';
409-
let currentCandidates = [];
410410
let isEnglishMode = false;
411-
let shiftTimer = null;
412-
const textOutput = document.getElementById('text-output');
411+
412+
const output = document.getElementById('text-output');
413413
const mainInput = document.getElementById('main-input');
414-
const candidateDisplay = document.getElementById('candidate-display');
414+
const candidateArea = document.getElementById('candidate-display');
415+
const keyboard = document.querySelector('.keyboard-container');
415416
const searchInput = document.getElementById('search-input');
416417
const searchResult = document.getElementById('search-result');
417418
const modeDisplay = document.getElementById('mode-display');
418-
const modeSwitcher = document.querySelector('.mode-switcher');
419-
const keyboardContainer = document.querySelector('.keyboard-container');
420419

421-
// --- 載入碼表檔案 ---
420+
// --- 載入碼表檔案(已修復) ---
422421
async function loadCodemap(filePath) {
423422
try {
424423
const response = await fetch(filePath);
@@ -433,14 +432,14 @@ <h2>輸入法模式:</h2>
433432
return { forward: {}, reverse: {} };
434433
}
435434
}
436-
437-
// --- 解析 Cin 格式檔案內容 ---
435+
436+
// --- 解析 Cin 格式檔案內容(已修復) ---
438437
function parseCinLikeFile(text) {
439438
const lines = text.split('\n');
440439
const codemap = {};
441440
const reverseCodemap = {};
442441
let inDataSection = false;
443-
442+
444443
for (const line of lines) {
445444
const trimmedLine = line.trim();
446445
if (trimmedLine.startsWith('[data]')) {
@@ -457,12 +456,11 @@ <h2>輸入法模式:</h2>
457456
codemap[code] = [];
458457
}
459458
codemap[code].push(...chars.split(''));
460-
459+
461460
chars.split('').forEach(char => {
462461
if (!reverseCodemap[char]) {
463462
reverseCodemap[char] = [];
464463
}
465-
// 避免重複編碼
466464
if (!reverseCodemap[char].includes(code)) {
467465
reverseCodemap[char].push(code);
468466
}
@@ -478,15 +476,15 @@ <h2>輸入法模式:</h2>
478476

479477
// --- 輸入法核心邏輯 ---
480478
function updateCandidates() {
481-
candidateDisplay.innerHTML = '';
479+
candidateArea.innerHTML = '';
482480
currentCandidates = currentCodemap[currentCode] || [];
483-
481+
484482
if (currentCode.length > 0) {
485483
const codeSpan = document.createElement('span');
486484
codeSpan.textContent = `[${currentCode}]`;
487485
codeSpan.style.color = '#7986cb';
488486
codeSpan.style.fontWeight = 'bold';
489-
candidateDisplay.appendChild(codeSpan);
487+
candidateArea.appendChild(codeSpan);
490488
}
491489

492490
if (currentCandidates.length > 0) {
@@ -495,13 +493,13 @@ <h2>輸入法模式:</h2>
495493
candidateSpan.textContent = `${index + 1}. ${char}`;
496494
candidateSpan.dataset.char = char;
497495
candidateSpan.dataset.index = index;
498-
candidateDisplay.appendChild(candidateSpan);
496+
candidateArea.appendChild(candidateSpan);
499497
});
500498
} else if (currentCode.length > 0) {
501499
const noCandidatesSpan = document.createElement('span');
502500
noCandidatesSpan.textContent = '找不到字';
503501
noCandidatesSpan.style.color = 'red';
504-
candidateDisplay.appendChild(noCandidatesSpan);
502+
candidateArea.appendChild(noCandidatesSpan);
505503
}
506504
}
507505

@@ -511,24 +509,22 @@ <h2>輸入法模式:</h2>
511509
updateCandidates();
512510
}
513511

514-
// --- 鍵盤與模式切換 ---
515-
function switchInputMethod(mode) {
516-
if (mode === 'primary') {
512+
// --- 模式與鍵盤處理 ---
513+
function switchInputMethod(method) {
514+
if (method === 'primary') {
517515
currentCodemap = primaryCodemap.forward;
518516
currentReverseCodemap = primaryCodemap.reverse;
519-
modeDisplay.textContent = '模式:三碼';
520517
} else {
521518
currentCodemap = secondaryCodemap.forward;
522519
currentReverseCodemap = secondaryCodemap.reverse;
523-
modeDisplay.textContent = '模式:三碼次常';
524520
}
525521
resetInputState();
526-
const radioButtons = modeSwitcher.querySelectorAll('input[type="radio"]');
527-
radioButtons.forEach(radio => {
528-
if (radio.value === mode) {
529-
radio.checked = true;
530-
}
531-
});
522+
updateModeDisplay();
523+
}
524+
525+
function updateModeDisplay() {
526+
const modeName = document.querySelector('input[name="input_mode"]:checked').nextElementSibling.textContent;
527+
modeDisplay.textContent = `模式:${isEnglishMode ? '英數' : modeName}`;
532528
}
533529

534530
// --- 事件處理 ---
@@ -541,165 +537,126 @@ <h2>輸入法模式:</h2>
541537
updateCandidates();
542538
});
543539

544-
// 監聽鍵盤點擊事件
545-
keyboardContainer.addEventListener('click', (event) => {
546-
const keyDiv = event.target.closest('.key');
547-
if (!keyDiv) return;
548-
549-
const code = keyDiv.dataset.code;
550-
handleKey(code);
551-
});
552-
553-
// 監聽候選字點擊事件
554-
candidateDisplay.addEventListener('click', (event) => {
555-
const candidateSpan = event.target.closest('span');
556-
if (candidateSpan && candidateSpan.dataset.char) {
557-
textOutput.textContent += candidateSpan.dataset.char;
558-
resetInputState();
559-
}
560-
});
561-
562-
// 監聽模式切換
563-
modeSwitcher.addEventListener('change', (event) => {
540+
document.querySelector('.mode-switcher').addEventListener('change', (event) => {
564541
if (event.target.name === 'input_mode') {
565542
switchInputMethod(event.target.value);
566543
}
567544
});
568-
569-
// 監聽反向查詢輸入
570-
searchInput.addEventListener('input', () => {
571-
const charToSearch = searchInput.value.trim();
572-
searchResult.textContent = '查詢結果顯示在此';
573-
if (charToSearch.length === 1) {
574-
const codes = currentReverseCodemap[charToSearch] || [];
575-
if (codes.length > 0) {
576-
searchResult.textContent = `編碼:${codes.join('、')}`;
577-
} else {
578-
searchResult.textContent = '找不到該漢字編碼。';
579-
}
545+
546+
candidateArea.addEventListener('click', (event) => {
547+
const candidate = event.target.closest('span[data-char]');
548+
if (candidate) {
549+
const char = candidate.dataset.char;
550+
output.textContent += char;
551+
resetInputState();
580552
}
581553
});
582554

583-
// 處理鍵盤輸入事件
584-
function handleKey(key) {
585-
if (isEnglishMode) {
586-
if (key === 'backspace') {
587-
textOutput.textContent = textOutput.textContent.slice(0, -1);
588-
} else if (key === 'enter') {
589-
textOutput.textContent += '\n';
590-
} else if (key === 'shift') {
591-
isEnglishMode = false;
592-
modeDisplay.textContent = '模式:三碼';
593-
} else {
594-
textOutput.textContent += key;
595-
}
596-
return;
597-
}
598-
599-
// 中文模式
600-
const validKeys = "abcdefghijklmnopqrstuvwxyz;,.";
601-
if (validKeys.includes(key) && currentCode.length < 3) {
602-
currentCode += key;
603-
mainInput.value = currentCode;
604-
updateCandidates();
605-
} else if (key === 'backspace') {
606-
if (currentCode.length > 0) {
607-
currentCode = currentCode.slice(0, -1);
608-
mainInput.value = currentCode;
609-
updateCandidates();
610-
} else {
611-
textOutput.textContent = textOutput.textContent.slice(0, -1);
612-
}
613-
} else if (key === ' ') {
614-
if (currentCandidates.length > 0) {
615-
textOutput.textContent += currentCandidates[0];
616-
resetInputState();
617-
} else {
618-
textOutput.textContent += ' ';
619-
}
620-
} else if (!isNaN(parseInt(key, 10))) {
621-
const index = parseInt(key, 10) - 1;
622-
if (index >= 0 && index < currentCandidates.length) {
623-
textOutput.textContent += currentCandidates[index];
624-
resetInputState();
625-
}
626-
} else if (key === 'shift') {
627-
isEnglishMode = true;
628-
modeDisplay.textContent = '模式:英數';
629-
resetInputState();
630-
} else if (key === 'enter') {
631-
textOutput.textContent += '\n';
632-
resetInputState();
633-
} else {
634-
textOutput.textContent += key;
635-
}
636-
}
555+
// 監聽鍵盤點擊事件
556+
keyboard.addEventListener('click', (event) => {
557+
const keyDiv = event.target.closest('.key');
558+
if (!keyDiv) return;
559+
const key = keyDiv.dataset.code;
560+
handleKey(key);
561+
});
637562

638-
// 監聽實體鍵盤
563+
// 監聽實體鍵盤事件
639564
document.addEventListener('keydown', (event) => {
640565
const key = event.key.toLowerCase();
641566
const keyMap = {
642567
'backspace': 'backspace',
643568
'enter': 'enter',
644569
' ': ' ',
645570
'shift': 'shift',
646-
'~': '`',
647-
'!': '1',
648-
'@': '2',
649-
'#': '3',
650-
'$': '4',
651-
'%': '5',
652-
'^': '6',
653-
'&': '7',
654-
'*': '8',
655-
'(': '9',
656-
')': '0',
657-
'-': '-',
658-
'=': '=',
659-
'[': '[',
660-
']': ']',
661-
'\\': '\\',
662-
';': ';',
663-
"'": "'",
664-
',': ',',
665-
'.': '.',
666-
'/': '/',
571+
'~': '~',
572+
'!' : '1', '@' : '2', '#' : '3', '$' : '4', '%' : '5', '^' : '6', '&' : '7', '*' : '8', '(' : '9', ')' : '0',
573+
'-': '-', '=': '=', '[': '[', ']': ']', '\\': '\\', ';': ';', "'": "'", ',': ',', '.': '.', '/': '/',
667574
'q': 'q', 'w': 'w', 'e': 'e', 'r': 'r', 't': 't', 'y': 'y', 'u': 'u', 'i': 'i', 'o': 'o', 'p': 'p',
668575
'a': 'a', 's': 's', 'd': 'd', 'f': 'f', 'g': 'g', 'h': 'h', 'j': 'j', 'k': 'k', 'l': 'l',
669576
'z': 'z', 'x': 'x', 'c': 'c', 'v': 'v', 'b': 'b', 'n': 'n', 'm': 'm'
670577
};
671578

579+
const inputKey = keyMap[key] || key;
580+
581+
// 處理 Shift 鍵切換模式
672582
if (event.key === "Shift") {
673-
if (event.repeat) return;
583+
if (event.repeat) return; // 避免長按時重複觸發
674584
isEnglishMode = !isEnglishMode;
675-
modeDisplay.textContent = isEnglishMode ? '模式:英數' : '模式:三碼';
585+
updateModeDisplay();
676586
resetInputState();
587+
event.preventDefault(); // 阻止瀏覽器默認行為
677588
return;
678589
}
679590

680591
// 在英數模式下處理所有輸入
681592
if (isEnglishMode) {
682-
if (event.key.length === 1 || event.key === 'Backspace' || event.key === 'Enter') {
683-
textOutput.textContent += event.key;
593+
if (event.key.length === 1) {
594+
output.textContent += event.key;
595+
} else if (event.key === 'Backspace') {
596+
output.textContent = output.textContent.slice(0, -1);
597+
} else if (event.key === 'Enter') {
598+
output.textContent += '\n';
684599
}
685600
return;
686601
}
687602

688603
// 在中文模式下處理
689-
const inputKey = keyMap[key];
690604
if (inputKey) {
691605
event.preventDefault(); // 阻止瀏覽器默認行為
692606
handleKey(inputKey);
693607
} else if (event.key >= '1' && event.key <= '9') {
694608
const index = parseInt(event.key, 10) - 1;
695609
if (index < currentCandidates.length) {
696-
textOutput.textContent += currentCandidates[index];
610+
output.textContent += currentCandidates[index];
697611
resetInputState();
698612
}
699613
} else if (event.key.length === 1) { // 處理未映射的單個字元
700-
textOutput.textContent += event.key;
614+
output.textContent += event.key;
701615
}
702616
});
703-
</script>
704617

618+
// 處理鍵盤與物理鍵盤的共用邏輯
619+
function handleKey(key) {
620+
const validCodeKeys = "1234567890abcdefghijklmnopqrstuvwxyz;',./";
621+
622+
if (validCodeKeys.includes(key) && currentCode.length < 3) {
623+
currentCode += key;
624+
mainInput.value = currentCode;
625+
updateCandidates();
626+
} else if (key === 'backspace') {
627+
if (currentCode.length > 0) {
628+
currentCode = currentCode.slice(0, -1);
629+
mainInput.value = currentCode;
630+
updateCandidates();
631+
} else {
632+
output.textContent = output.textContent.slice(0, -1);
633+
}
634+
} else if (key === ' ') {
635+
if (currentCandidates.length > 0) {
636+
output.textContent += currentCandidates[0];
637+
resetInputState();
638+
} else {
639+
output.textContent += ' ';
640+
}
641+
} else if (key === 'enter') {
642+
output.textContent += '\n';
643+
resetInputState();
644+
}
645+
}
646+
647+
// --- 反向查詢事件處理 ---
648+
searchInput.addEventListener('input', () => {
649+
const charToSearch = searchInput.value.trim();
650+
searchResult.textContent = '查詢結果顯示在此';
651+
if (charToSearch.length === 1) {
652+
const codes = currentReverseCodemap[charToSearch] || [];
653+
if (codes.length > 0) {
654+
searchResult.textContent = `編碼:${codes.join('、')}`;
655+
} else {
656+
searchResult.textContent = '找不到該漢字編碼。';
657+
}
658+
}
659+
});
660+
661+
</script>
705662
</body></html>

0 commit comments

Comments
 (0)