Skip to content

Commit 39f1fbc

Browse files
authored
Update test.html
1 parent e7675f5 commit 39f1fbc

1 file changed

Lines changed: 113 additions & 64 deletions

File tree

test.html

Lines changed: 113 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,8 @@ <h2>輸入法模式:</h2>
408408
let currentCodemap = {};
409409
let currentReverseCodemap = {};
410410
let isEnglishMode = false;
411+
let currentPage = 0;
412+
const candidatesPerPage = 10;
411413

412414
const output = document.getElementById('text-output');
413415
const mainInput = document.getElementById('main-input');
@@ -423,7 +425,7 @@ <h2>輸入法模式:</h2>
423425
';': ';', "'": '〃', ',': ',', '.': '.', '/': '/'
424426
};
425427

426-
// --- 載入碼表檔案(已修復) ---
428+
// --- 載入碼表檔案 ---
427429
async function loadCodemap(filePath) {
428430
try {
429431
const response = await fetch(filePath);
@@ -439,7 +441,7 @@ <h2>輸入法模式:</h2>
439441
}
440442
}
441443

442-
// --- 解析 Cin 格式檔案內容(已修復) ---
444+
// --- 解析 Cin 格式檔案內容 ---
443445
function parseCinLikeFile(text) {
444446
const lines = text.split('\n');
445447
const codemap = {};
@@ -484,23 +486,53 @@ <h2>輸入法模式:</h2>
484486
function updateCandidates() {
485487
candidateArea.innerHTML = '';
486488
currentCandidates = currentCodemap[currentCode] || [];
489+
490+
if (currentCandidates.length === 1 && currentCode.length === 3) {
491+
output.textContent += currentCandidates[0];
492+
resetInputState();
493+
return;
494+
}
495+
496+
const totalPages = Math.ceil(currentCandidates.length / candidatesPerPage);
497+
const startIndex = currentPage * candidatesPerPage;
498+
const endIndex = startIndex + candidatesPerPage;
499+
const displayedCandidates = currentCandidates.slice(startIndex, endIndex);
487500

488-
if (currentCandidates.length > 0) {
489-
currentCandidates.forEach((char, index) => {
501+
if (displayedCandidates.length > 0) {
502+
displayedCandidates.forEach((char, index) => {
490503
const candidateSpan = document.createElement('span');
491-
candidateSpan.textContent = `${index + 1}. ${char}`;
504+
const displayIndex = (index === 9) ? 0 : index + 1;
505+
candidateSpan.textContent = `${displayIndex}. ${char}`;
492506
candidateSpan.dataset.char = char;
493507
candidateSpan.dataset.index = index;
494508
candidateArea.appendChild(candidateSpan);
495509
});
496510
} else if (currentCode.length === 3) {
497511
resetInputState();
498512
}
513+
514+
if (totalPages > 1) {
515+
if (currentPage > 0) {
516+
const prevSpan = document.createElement('span');
517+
prevSpan.textContent = '上一頁';
518+
prevSpan.className = 'page-nav';
519+
prevSpan.dataset.page = 'prev';
520+
candidateArea.prepend(prevSpan);
521+
}
522+
if (currentPage < totalPages - 1) {
523+
const nextSpan = document.createElement('span');
524+
nextSpan.textContent = '下一頁';
525+
nextSpan.className = 'page-nav';
526+
nextSpan.dataset.page = 'next';
527+
candidateArea.appendChild(nextSpan);
528+
}
529+
}
499530
}
500531

501532
function resetInputState() {
502533
currentCode = '';
503534
mainInput.value = '';
535+
currentPage = 0;
504536
updateCandidates();
505537
}
506538

@@ -540,10 +572,18 @@ <h2>輸入法模式:</h2>
540572

541573
candidateArea.addEventListener('click', (event) => {
542574
const candidate = event.target.closest('span[data-char]');
575+
const pageNav = event.target.closest('span[data-page]');
543576
if (candidate) {
544577
const char = candidate.dataset.char;
545578
output.textContent += char;
546579
resetInputState();
580+
} else if (pageNav) {
581+
if (pageNav.dataset.page === 'next') {
582+
currentPage++;
583+
} else if (pageNav.dataset.page === 'prev') {
584+
currentPage--;
585+
}
586+
updateCandidates();
547587
}
548588
});
549589

@@ -555,42 +595,38 @@ <h2>輸入法模式:</h2>
555595
handleKey(key);
556596
});
557597

598+
const specialKeys = ["backspace", "enter", " "];
599+
const pageKeys = ["<", ">"];
600+
const numKeys = "1234567890";
601+
const codeKeys = "abcdefghijklmnopqrstuvwxyz;',./";
602+
558603
// 監聽實體鍵盤事件
559604
document.addEventListener('keydown', (event) => {
560605
const key = event.key.toLowerCase();
561-
const keyMap = {
562-
'backspace': 'backspace',
563-
'enter': 'enter',
564-
' ': ' ',
565-
'shift': 'shift',
566-
'~': '~',
567-
'1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9', '0': '0',
568-
';': ';', "'": "'", ',': ',', '.': '.', '/': '/',
569-
'q': 'q', 'w': 'w', 'e': 'e', 'r': 'r', 't': 't', 'y': 'y', 'u': 'u', 'i': 'i', 'o': 'o', 'p': 'p',
570-
'a': 'a', 's': 's', 'd': 'd', 'f': 'f', 'g': 'g', 'h': 'h', 'j': 'j', 'k': 'K', 'l': 'l',
571-
'z': 'z', 'x': 'x', 'c': 'c', 'v': 'v', 'b': 'b', 'n': 'n', 'm': 'm'
572-
};
573-
const inputKey = keyMap[key] || key;
574606

575607
// 處理按鍵反白效果
576-
const pressedKey = document.querySelector(`.key[data-code='${inputKey}']`);
577-
if (pressedKey) {
578-
pressedKey.classList.add('active');
608+
let pressedKeyDiv;
609+
if (key === '<') {
610+
pressedKeyDiv = document.querySelector(`.key[data-code='&lt;']`);
611+
} else if (key === '>') {
612+
pressedKeyDiv = document.querySelector(`.key[data-code='&gt;']`);
613+
} else {
614+
pressedKeyDiv = document.querySelector(`.key[data-code='${key}']`);
615+
}
616+
if (pressedKeyDiv) {
617+
pressedKeyDiv.classList.add('active');
579618
}
580619

581-
// 處理 Shift 鍵切換模式
582620
if (event.key === "Shift") {
583-
if (event.repeat) return; // 避免長按時重複觸發
621+
if (event.repeat) return;
584622
isEnglishMode = !isEnglishMode;
585623
updateModeDisplay();
586624
resetInputState();
587-
event.preventDefault(); // 阻止瀏覽器默認行為
588-
return;
625+
return;
589626
}
590627

591-
// 在英數模式下處理所有輸入
592628
if (isEnglishMode) {
593-
if (event.key.length === 1) {
629+
if (key.length === 1 && !event.ctrlKey && !event.altKey) {
594630
output.textContent += event.key;
595631
} else if (event.key === 'Backspace') {
596632
output.textContent = output.textContent.slice(0, -1);
@@ -600,57 +636,41 @@ <h2>輸入法模式:</h2>
600636
return;
601637
}
602638

603-
// 在中文模式下處理
604-
// 數字鍵處理邏輯:有候選字則選字,無候選字則上字
605-
if (event.key >= '1' && event.key <= '9') {
606-
event.preventDefault(); // 阻止瀏覽器默認行為
607-
const index = parseInt(event.key, 10) - 1;
608-
if (currentCandidates.length > 0 && index >= 0 && index < currentCandidates.length) {
609-
output.textContent += currentCandidates[index];
610-
resetInputState();
611-
} else {
612-
output.textContent += event.key;
613-
resetInputState();
614-
}
615-
} else if (event.key === '0') {
616-
event.preventDefault();
617-
output.textContent += event.key;
618-
resetInputState();
619-
} else if (inputKey) {
620-
event.preventDefault(); // 阻止瀏覽器默認行為
621-
handleKey(inputKey);
622-
} else if (event.key.length === 1) { // 處理未映射的單個字元
623-
output.textContent += event.key;
639+
if (specialKeys.includes(key)) {
640+
event.preventDefault();
641+
handleKey(key);
642+
} else if (pageKeys.includes(key)) {
643+
event.preventDefault();
644+
handlePageKey(key);
645+
} else if (numKeys.includes(key)) {
646+
event.preventDefault();
647+
handleNumKey(key);
648+
} else if (codeKeys.includes(key)) {
649+
handleKey(key);
624650
}
625651
});
626652

627653
// 監聽實體鍵盤放開事件,移除按鍵反白
628654
document.addEventListener('keyup', (event) => {
629655
const key = event.key.toLowerCase();
630-
const keyMap = {
631-
'backspace': 'backspace',
632-
'enter': 'enter',
633-
' ': ' ',
634-
'shift': 'shift',
635-
'~': '~',
636-
'1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9', '0': '0',
637-
';': ';', "'": "'", ',': ',', '.': '.', '/': '/',
638-
'q': 'q', 'w': 'w', 'e': 'e', 'r': 'r', 't': 't', 'y': 'y', 'u': 'u', 'i': 'i', 'o': 'o', 'p': 'p',
639-
'a': 'a', 's': 's', 'd': 'd', 'f': 'f', 'g': 'g', 'h': 'h', 'j': 'j', 'k': 'K', 'l': 'l',
640-
'z': 'z', 'x': 'x', 'c': 'c', 'v': 'v', 'b': 'b', 'n': 'n', 'm': 'm'
641-
};
642-
const releasedKey = keyMap[key] || key;
643-
const releasedKeyDiv = document.querySelector(`.key[data-code='${releasedKey}']`);
656+
let releasedKeyDiv;
657+
if (key === '<') {
658+
releasedKeyDiv = document.querySelector(`.key[data-code='&lt;']`);
659+
} else if (key === '>') {
660+
releasedKeyDiv = document.querySelector(`.key[data-code='&gt;']`);
661+
} else {
662+
releasedKeyDiv = document.querySelector(`.key[data-code='${key}']`);
663+
}
644664
if (releasedKeyDiv) {
645665
releasedKeyDiv.classList.remove('active');
646666
}
647667
});
648668

649669
// 處理鍵盤與物理鍵盤的共用邏輯
650670
function handleKey(key) {
651-
const validCodeKeys = "1234567890abcdefghijklmnopqrstuvwxyz;',./";
671+
const codeKeys = "abcdefghijklmnopqrstuvwxyz;',./";
652672

653-
if (validCodeKeys.includes(key) && currentCode.length < 3) {
673+
if (codeKeys.includes(key) && currentCode.length < 3) {
654674
currentCode += key;
655675
const fullWidthCode = Array.from(currentCode).map(char => fullWidthMap[char] || char).join('');
656676
mainInput.value = fullWidthCode;
@@ -676,6 +696,35 @@ <h2>輸入法模式:</h2>
676696
resetInputState();
677697
}
678698
}
699+
700+
function handlePageKey(key) {
701+
if (key === '<') {
702+
if (currentPage > 0) {
703+
currentPage--;
704+
updateCandidates();
705+
}
706+
} else if (key === '>') {
707+
const totalPages = Math.ceil(currentCandidates.length / candidatesPerPage);
708+
if (currentPage < totalPages - 1) {
709+
currentPage++;
710+
updateCandidates();
711+
}
712+
}
713+
}
714+
715+
function handleNumKey(key) {
716+
let index = parseInt(key, 10);
717+
if (index === 0) index = 10;
718+
719+
const candidateIndex = (currentPage * candidatesPerPage) + (index - 1);
720+
if (candidateIndex >= 0 && candidateIndex < currentCandidates.length) {
721+
output.textContent += currentCandidates[candidateIndex];
722+
resetInputState();
723+
} else {
724+
output.textContent += key;
725+
resetInputState();
726+
}
727+
}
679728

680729
// --- 反向查詢事件處理 ---
681730
searchInput.addEventListener('input', () => {

0 commit comments

Comments
 (0)