代码: 全选
你好!為輸入法添加「頂字上屏」、「長按連續輸出」及「多字符查詢」功能,需要修改原本的 HTML、CSS 以及 JavaScript 代碼。
以下為具體的修改位置及代碼:
### 1. 修改 HTML 查詢區域文字與標籤
將原本 `maxlength="1"` 的限制移除,並修改提示文字。
**尋找:**
```html
<div class="search_box hide">
<div class="vm"></div><div class="ib">
<div class="search_box_tile">請輸入一個漢字:</div>
<input class="search_box_input" type="input" maxlength="1">
<div>
<span class="search_box_go">查詢</span>
</div>
</div>
<div class="multiplebox"></div>
</div>
```
**替換為:**
```html
<div class="search_box hide">
<div class="vm"></div><div class="ib">
<div class="search_box_tile">請輸入所要查詢的字符:</div>
<input class="search_box_input" type="input">
<div>
<span class="search_box_go">查詢</span>
</div>
</div>
<div class="multiplebox"></div>
</div>
```
---
### 2. 修改 CSS 查詢輸入框寬度與文字置中
將輸入框加寬到大約五個漢字的寬度,並讓文字居中。
**尋找:**
```css
.search_box_input {font-size: 36px; height: 48px; width: 48px; margin: 3vh 0;}
```
**替換為:**
```css
.search_box_input {font-size: 36px; height: 48px; width: 240px; margin: 3vh 0; text-align: center;}
```
---
### 3. 修改 JS 以支援實體鍵盤「頂字上屏」
在監聽實體鍵盤輸入時,判斷是否達到 `cin_max` 且候選區有字。
**尋找:**
```javascript
// a~z
if (e.keyCode >= 65 && e.keyCode <= 90 && !e.ctrlKey && !e.shiftKey) {
e.preventDefault();
if (pre_input.length < cin_max) {
pre_input += e.key.toLowerCase();
pre_input_c += e2c[e.key.toLowerCase()];
display_input();
} else {
pre_input += e.key.toLowerCase();
}
}
```
**替換為:**
```javascript
// a~z
if (e.keyCode >= 65 && e.keyCode <= 90 && !e.ctrlKey && !e.shiftKey) {
e.preventDefault();
if (pre_input.length == cin_max && pre_input_zh.length > 0) {
send_char(pre_input_zh[0]);
pre_input = e.key.toLowerCase();
pre_input_c = e2c[e.key.toLowerCase()];
display_input();
} else if (pre_input.length < cin_max) {
pre_input += e.key.toLowerCase();
pre_input_c += e2c[e.key.toLowerCase()];
display_input();
} else {
pre_input += e.key.toLowerCase();
}
}
```
---
### 4. 增加 JS「長按連續輸出」計時器並綁定觸屏事件
在宣告點擊事件前,插入長按計時的共用函數。
**尋找:**
```javascript
// Use pointerdown for the keyboard to ensure instantaneous response
ejcjonline_keyboard.addEventListener("pointerdown", ejcjclick);
// Use click for the display area to allow horizontal touch scrolling
ejcjonline_display.addEventListener("click", ejcjclick);
// click event
function ejcjclick(e) {
```
**替換為:**
```javascript
let lpTimer, lpInterval;
function startLongPress(action) {
action(); // 立即執行第一次
lpTimer = setTimeout(function() {
lpInterval = setInterval(action, 80); // 長按 400 毫秒後,每 80 毫秒連續觸發
}, 400);
}
function stopLongPress() {
clearTimeout(lpTimer);
clearInterval(lpInterval);
}
// 全局監聽放開或中斷事件,用以停止長按
window.addEventListener("pointerup", stopLongPress);
window.addEventListener("pointercancel", stopLongPress);
// Use pointerdown for the keyboard to ensure instantaneous response
ejcjonline_keyboard.addEventListener("pointerdown", ejcjclick);
// Use click for the display area to allow horizontal touch scrolling
ejcjonline_display.addEventListener("click", ejcjclick);
// click event
function ejcjclick(e) {
```
---
### 5. 修改 JS 以支援觸控鍵盤「頂字上屏」
在螢幕虛擬鍵盤點擊輸入時加入與實體鍵盤相同的判斷邏輯。
**尋找:**
```javascript
// ejcjonline_key
// a~z
if (e.target.classList.contains("ejcjonline_key")) {
if (zh_mode){
if (pre_input.length < cin_max) {
pre_input += e.target.getAttribute("kname");
pre_input_c += e.target.innerHTML;
display_input();
} else {
pre_input += e.target.getAttribute("kname");
}
} else {
```
**替換為:**
```javascript
// ejcjonline_key
// a~z
if (e.target.classList.contains("ejcjonline_key")) {
if (zh_mode){
let k = e.target.getAttribute("kname");
let c = e.target.innerHTML;
if (pre_input.length == cin_max && pre_input_zh.length > 0) {
send_char(pre_input_zh[0]);
pre_input = k;
pre_input_c = c;
display_input();
} else if (pre_input.length < cin_max) {
pre_input += k;
pre_input_c += c;
display_input();
} else {
pre_input += k;
}
} else {
```
---
### 6. 修改 JS 觸控鍵盤的「退格、回車」以支援長按
將這兩顆按鍵的執行邏輯包裝在我們剛寫好的 `startLongPress` 函數中。
**尋找:**
```javascript
// Back
else if (e.target.classList.contains("ejcjonline_fukey_back")) {
if (zh_mode && pre_input.length > 0) {
if (pre_input.length > cin_max) {
pre_input = pre_input.substr(0, pre_input.length - 1);
} else {
pre_input = pre_input.substr(0, pre_input.length - 1);
pre_input_c = pre_input_c.substr(0, pre_input_c.length - 1);
display_input();
}
} else {
send_char("\b");
}
}
// Esc
else if (e.target.classList.contains("ejcjonline_fukey_esc")) {
if (zh_mode && pre_input.length > 0) {
pre_input = '';
pre_input_c = '';
display_input();
}
}
// Enter
else if (e.target.classList.contains("ejcjonline_fukey_enter")) {
if (zh_mode && pre_input.length > 0) {
send_char(pre_input);
pre_input = '';
pre_input_c = '';
display_input();
} else {
send_char("\n");
}
}
```
**替換為:**
```javascript
// Back
else if (e.target.classList.contains("ejcjonline_fukey_back")) {
startLongPress(function() {
if (zh_mode && pre_input.length > 0) {
if (pre_input.length > cin_max) {
pre_input = pre_input.substr(0, pre_input.length - 1);
} else {
pre_input = pre_input.substr(0, pre_input.length - 1);
pre_input_c = pre_input_c.substr(0, pre_input_c.length - 1);
display_input();
}
} else {
send_char("\b");
}
});
}
// Esc
else if (e.target.classList.contains("ejcjonline_fukey_esc")) {
if (zh_mode && pre_input.length > 0) {
pre_input = '';
pre_input_c = '';
display_input();
}
}
// Enter
else if (e.target.classList.contains("ejcjonline_fukey_enter")) {
startLongPress(function() {
if (zh_mode && pre_input.length > 0) {
send_char(pre_input);
pre_input = '';
pre_input_c = '';
display_input();
} else {
send_char("\n");
}
});
}
```
---
### 7. 修改 JS「光標前移、光標後移」以支援長按
將原本使用 `onclick` 改為 `pointerdown`,並包裝進 `startLongPress` 函數。
**尋找:**
```javascript
// move left
topbtnmoveleft.onclick = function () {
input_area.focus();
if (0 != input_area.selectionStart) {
input_area.selectionStart = input_area.selectionStart - 1;
input_area.selectionEnd = input_area.selectionStart;
}
input_area.blur();
move_button();
blink();
}
// move right
topbtnmoveright.onclick = function () {
input_area.focus();
if (input_area.value.length != input_area.selectionEnd) {
input_area.selectionEnd = input_area.selectionEnd + 1;
input_area.selectionStart = input_area.selectionEnd;
}
input_area.blur();
move_button();
blink();
}
```
**替換為:**
```javascript
// move left
topbtnmoveleft.addEventListener("pointerdown", function (e) {
e.preventDefault();
startLongPress(function() {
input_area.focus();
if (0 != input_area.selectionStart) {
input_area.selectionStart = input_area.selectionStart - 1;
input_area.selectionEnd = input_area.selectionStart;
}
input_area.blur();
move_button();
blink();
});
});
// move right
topbtnmoveright.addEventListener("pointerdown", function (e) {
e.preventDefault();
startLongPress(function() {
input_area.focus();
if (input_area.value.length != input_area.selectionEnd) {
input_area.selectionEnd = input_area.selectionEnd + 1;
input_area.selectionStart = input_area.selectionEnd;
}
input_area.blur();
move_button();
blink();
});
});
```
---
### 8. 修改 JS 查詢功能支援逐字多字符顯示
透過迴圈拆分字串,逐個匹配並統一顯示結果。
**尋找:**
```javascript
function searchClick () {
var search_box_input = document.querySelector(".search_box_input");
var multiplebox = document.querySelector(".multiplebox");
if (search_box_input.value) {
let pattern = new RegExp("^.*\t" + search_box_input.value + ".*$", "gm");
let search_result = cin_search.match(pattern);
if (search_result && search_result.length) {
pre_input = search_result[0].replace(/\t.*/, "");
pre_input_c = "";
for (let x = 0; x < pre_input.length; x++) {
pre_input_c += e2c[pre_input[x]];
}
search_box_input.value = '';
// search_result.length more than 1
if (search_result.length > 1) {
multiplebox.innerHTML = search_result
.map((m) => m.replace(/\t.*/, ""))
.toString();
} else {
multiplebox.innerHTML = "";
}
display_input();
// highlight search char
let cchar_single = document.querySelectorAll(".cchar_single");
let cchar_single_c = search_result[0].replace(/.*\t/, "")
for (let i = 0; i < cchar_single.length; i++) {
if (cchar_single[i].innerHTML == cchar_single_c) {
cchar_single[i].style.background = "#ac3";
}
}
} else {
pre_input_c = "查無此字";
display_input();
}
}
}
```
**替換為:**
```javascript
function searchClick () {
var search_box_input = document.querySelector(".search_box_input");
var multiplebox = document.querySelector(".multiplebox");
if (search_box_input.value) {
let chars = Array.from(search_box_input.value);
let allResults = [];
let foundFirst = "";
for (let i = 0; i < chars.length; i++) {
let pattern = new RegExp("^.*\t" + chars[i] + "$", "gm");
let search_result = cin_search.match(pattern);
if (search_result && search_result.length) {
let codes = search_result.map((m) => m.split("\t")[0]);
allResults.push(chars[i] + ":" + codes.join(", "));
if (!foundFirst) foundFirst = codes[0];
} else {
allResults.push(chars[i] + ":查無此字");
}
}
multiplebox.innerHTML = allResults.join("<br>");
if (foundFirst) {
pre_input = foundFirst;
pre_input_c = "";
for (let x = 0; x < pre_input.length; x++) {
pre_input_c += e2c[pre_input[x]];
}
display_input();
} else {
pre_input_c = "查無此字";
display_input();
}
search_box_input.value = '';
}
}
```