分享和討論倉頡輸入法相關的資訊和内容
版面规则
公正客觀講理,杜絶廢話連篇
回复
头像
ejsoon
一枝独秀
帖子: 6345
注册时间: 2022年 11月 18日 17:36
联系:

尹卂網頁輸入法功能改進

帖子 ejsoon »

gemini 3.1 pro

代码: 全选

你好!為輸入法添加「頂字上屏」、「長按連續輸出」及「多字符查詢」功能,需要修改原本的 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 = '';
	}
}

```
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀
帖子: 6345
注册时间: 2022年 11月 18日 17:36
联系:

Re: 尹卂網頁輸入法功能改進

帖子 ejsoon »

ejime_haha_20260725.html
附件
ejime_haha_20260725.html.7z
(128.4 KiB) 已下载 1 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀
帖子: 6345
注册时间: 2022年 11月 18日 17:36
联系:

Re: 尹卂網頁輸入法功能改進

帖子 ejsoon »

修復與改進:
一,連續刪除和連續回車會彈出系統輸入法

當在手機端長按刪除或回車時,會彈出系統輸入法。查找原因並修復。

二,查詣功能修復

在查詢功能中,當輸入一個字符,按enter後,將顯示查詢結果。但這時如果再輸入一個字符,按enter,卻不會再出現查詢結果。關閉查詢,發現前一次查詢的英文進入了輸入框。應改為處於查詢狀態時,按enter或任何鍵都不會對輸入框產生影響。

查詢功能應精準匹配,如果輸入的是一個漢字,則匹配這個漢字,如果輸入的是多個字組成的詞語,則匹配這個詞語的編碼。如果匹配到多個編碼,才會在下方中間的小字中顯示全部匹配到的編碼(僅顯示編碼而不要顯示所查詢的字)。

請明確給出所要修改的地方和所要替換的代碼。

gemini 3.1 pro

代码: 全选

這兩個問題的成因都很明確。

第一個問題是因為在執行長按功能(`startLongPress`)時,會不斷觸發 `send_char`,而 `send_char` 內有一句 `input_area.focus();` 會強制文字框獲取焦點,導致手機系統判斷需要彈出鍵盤。我們只要在執行後立刻調用 `blur()` 移除焦點即可。

第二個問題分為兩部分:

1. **輸入框被干擾**:這是因為 `ejcjkeydown` 事件監聽器是全域綁定的。當你在查詢框按下 Enter 甚至輸入字母時,程式仍會把它當作一般輸入法的按鍵來處理,進而汙染了變數並觸發行為。我們需要在這個函數開頭判斷「是否正在查詢」,如果是就直接跳出。
2. **精準匹配與多重編碼顯示**:原有的搜尋邏輯是把輸入的值拆成單個字符 `Array.from(search_box_input.value)` 來分別查詢,因此要改寫為「整段字串直接比對」,並判斷匹配到的結果數量來決定要不要在下方顯示。

以下是具體的修改位置與替換代碼:

### 修改一:修復連續刪除與回車彈出系統輸入法

請找到代碼中的 `startLongPress` 函數(大約在行數 466 附近):

**【所要修改的地方】**

```javascript
function startLongPress(action) {
	action(); // 立即執行第一次
	lpTimer = setTimeout(function() {
		lpInterval = setInterval(action, 36);
	}, 240); 
}

```

**【替換為以下代碼】**

```javascript
function startLongPress(action) {
	action(); // 立即執行第一次
	input_area.blur(); // 執行後馬上移除焦點,防止彈出系統鍵盤
	lpTimer = setTimeout(function() {
		lpInterval = setInterval(function() {
			action();
			input_area.blur(); // 持續執行時也確保移除焦點
		}, 36);
	}, 240); 
}

```

---

### 修改二:修復查詢狀態下按鍵衝突

請找到鍵盤事件 `ejcjkeydown(e)` 的開頭處(大約在行數 334 附近):

**【所要修改的地方】**

```javascript
function ejcjkeydown(e) {
	/*
	a~z			65~90
	Shift		16
	Ctrl		17
	Esc			27
	Whitespace	32
	Back		8
	Enter		13
	1~3			49~51
	4~9			52~57
	0			48
	;			59(firefox)		186(chromium)
	'			222
	,			188
	.			190
	/			191
	*/
	// console.log('e.keyCode', e.keyCode);
	if (eoinfo.classList.contains("hide")) {
		input_area.focus();
	}
	// Shift

```

**【替換為以下代碼】**

```javascript
function ejcjkeydown(e) {
	/*
	a~z			65~90
	Shift		16
	Ctrl		17
	... (註解略)
	/			191
	*/
	// console.log('e.keyCode', e.keyCode);
	
	// 處於查詢狀態時,阻擋按鍵事件去影響主輸入框
	var search_box = document.querySelector(".search_box");
	if (!search_box.classList.contains("hide")) {
		return; 
	}
	
	if (eoinfo.classList.contains("hide")) {
		input_area.focus();
	}
	// Shift

```

---

### 修改三:重寫查詢邏輯(精準匹配與編碼顯示)

請找到 `searchClick()` 函數(大約在行數 666 附近):

**【所要修改的地方】**

```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 = '';
	}
}

```

**【替換為以下代碼】**

```javascript
function searchClick () {
	var search_box_input = document.querySelector(".search_box_input");
	var multiplebox = document.querySelector(".multiplebox");
	let query = search_box_input.value.trim();
	if (query) {
		let foundFirst = "";
		// 防止正則符號出錯
		let escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
		// 改為匹配整段詞彙,不再逐字拆分
		let pattern = new RegExp("^.*\t" + escapedQuery + "$", "gm");
		let search_result = cin_search.match(pattern);
		
		if (search_result && search_result.length) {
			let codes = search_result.map((m) => m.split("\t")[0]);
			foundFirst = codes[0];
			
			// 如果匹配到多個編碼,才會顯示在下方,且僅顯示編碼
			if (codes.length > 1) {
				multiplebox.innerHTML = codes.join(", ");
			} else {
				multiplebox.innerHTML = "";
			}
		} else {
			multiplebox.innerHTML = "查無此字";
			foundFirst = "";
		}
		
		if (foundFirst) {
			pre_input = foundFirst;
			pre_input_c = "";
			for (let x = 0; x < pre_input.length; x++) {
				pre_input_c += e2c[pre_input[x]] || pre_input[x];
			}
			display_input();
		} else {
			pre_input = "";
			pre_input_c = "查無此字";
			display_input();
		}
		
		search_box_input.value = '';
	}
}

```
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀
帖子: 6345
注册时间: 2022年 11月 18日 17:36
联系:

Re: 尹卂網頁輸入法功能改進

帖子 ejsoon »

當在手機端時,點擊輸入框,光標會去到那個地方,同時會彈出系統輸入法。把系統輸入法退出後,如果按字母鍵,不會彈出系統輸入法,這是對的,但是如果按「光標前進、光標後退、退格、回車」,系統輸入法會一閃而過。

查找原因並修復。

gemini 3.1 pro

代码: 全选

這是一個在手機端網頁開發中非常經典的「系統鍵盤閃爍」問題。你觀察得很仔細!

### 為什麼會閃爍?

在移動端瀏覽器中,只要針對輸入框(`textarea` 或 `input`)觸發了 `.focus()`,系統就會自動彈出虛擬鍵盤;而觸發 `.blur()` 則會收起鍵盤。

在你點擊「字母鍵」時,程式只會更新 `pre_input` 的字串並重新渲染顯示區,**並沒有**去 focus 輸入框,所以系統鍵盤不會彈出。

但是,當你點擊「光標前進」、「光標後退」、「退格」或「回車」時,程式內部調用的函式(如 `send_char` 或方向鍵的監聽器)裡,被強制寫入了 `input_area.focus()`,緊接著事件結尾又觸發了 `input_area.blur()`。這短暫的「獲取焦點又立刻失去焦點」的過程,就導致了系統鍵盤「一閃而過」。

### 解決方法

事實上,使用 JavaScript 修改 textarea 的 `value`、`selectionStart` 或 `selectionEnd` 時,**完全不需要先將該元素 focus**。只要把這些多餘的 `.focus()` 和 `.blur()` 刪除,就能完美解決閃爍問題。

請在你的 HTML 檔案中,找到並修改以下幾個部分:

#### 1. 修改 `send_char` 函式(解決退格、回車閃爍)

找到 `send_char(myValue)` 函式,將裡面(除 IE 支援部分外)的 `input_area.focus();` 全部移除或註解掉:

```javascript
function send_char(myValue) {
	//IE support
	if (document.selection) {
		input_area.focus(); // 這是上古 IE 專用,可以保留或刪除
		sel = document.selection.createRange();
		sel.text = myValue;
		sel.select();
	}
	else if (myValue == "\b") {
		var startPos = input_area.selectionStart;
		var endPos = input_area.selectionEnd;
		if (startPos == endPos && startPos != 0) {
			startPos -= 1;
		}
		input_area.value = input_area.value.substring(0, startPos)  + input_area.value.substring(endPos, input_area.value.length);
		// save scrollTop before insert chinese Cha
		var restoreTop = input_area.scrollTop;
		// input_area.focus();  <-- 【刪除此行】
		input_area.selectionStart = startPos;
		input_area.selectionEnd = startPos;
		if (input_area.selectionEnd != input_area.value.length) {
			input_area.scrollTo(0, restoreTop);
		}
	}
	//MOZILLA/NETSCAPE support
	else if (input_area.selectionStart || input_area.selectionStart == '0') {
		var startPos = input_area.selectionStart;
		var endPos = input_area.selectionEnd;
		// save scrollTop before insert chinese Cha
		var restoreTop = input_area.scrollTop;
		input_area.value = input_area.value.substring(0, startPos) + myValue + input_area.value.substring(endPos, input_area.value.length);
		// input_area.focus();  <-- 【刪除此行】
		input_area.selectionStart = startPos + myValue.length;
		input_area.selectionEnd = startPos + myValue.length;
		if (input_area.selectionEnd != input_area.value.length) {
			input_area.scrollTo(0, restoreTop);
		}
	} else {
		input_area.value += myValue;
		// input_area.focus();  <-- 【刪除此行】
	}
	localStorage.setItem("ejcjonline_value", input_area.value);
	localStorage.setItem("ejcjonline_start_value", input_area.selectionStart);
	tour_record();
	move_button();
}

```

#### 2. 修改光標左移/右移按鈕(解決方向鍵閃爍)

找到 `topbtnmoveleft` 和 `topbtnmoveright` 的事件監聽器,把裡面的 `input_area.focus();` 與 `input_area.blur();` 刪除:

```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();
	});
});

```

#### 3. 修改 Undo / Redo 按鈕(預防隱藏的閃爍)

雖然你沒提到,但在代碼中「復原 (`topbtnfallback`)」與「重做 (`topbtnredo`)」按鈕也有完全相同的寫法。為了避免日後點擊時也發生鍵盤閃爍,建議一併清理:

```javascript
// fallback tour
topbtnfallback.onclick = function () {
	if (tour_start != tour_point) {
		tour_point = (tour_point + 8) % 9;
		input_area.value = tour_array[tour_point][0];
		// input_area.focus(); <-- 【刪除此行】
		input_area.selectionEnd = input_area.selectionStart = tour_array[tour_point][1];
		// input_area.blur();  <-- 【刪除此行】
		topbtnredo.classList.remove("topbtngray");
		if (tour_start == tour_point) {
			topbtnfallback.classList.add("topbtngray");
		}
		blink();
	}
}

// redo
topbtnredo.onclick = function () {
	if (tour_end != tour_point) {
		tour_point = (tour_point + 1) % 9;
		input_area.value = tour_array[tour_point][0];
		// input_area.focus(); <-- 【刪除此行】
		input_area.selectionEnd = input_area.selectionStart = tour_array[tour_point][1];
		// input_area.blur();  <-- 【刪除此行】
		topbtnfallback.classList.remove("topbtngray");
		if (tour_end == tour_point) {
			topbtnredo.classList.add("topbtngray");
		}
		blink();
	}
}

```

改完這些後,在手機上使用所有虛擬按鍵功能時,系統鍵盤都不會再一閃而過了!而且你在 PC 端使用實體鍵盤時,輸入框本來就處於 focus 狀態,這些修改也不會影響 PC 端的正常輸入。
附件
ejime_haha_20260725_2.html.7z
(128.68 KiB) 尚未被下载
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀
帖子: 6345
注册时间: 2022年 11月 18日 17:36
联系:

Re: 尹卂網頁輸入法功能改進

帖子 ejsoon »

ejime_haha_20260725_21.html
附件
ejime_haha_20260725_21.html.7z
(128.56 KiB) 尚未被下载
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀
帖子: 6345
注册时间: 2022年 11月 18日 17:36
联系:

Re: 尹卂網頁輸入法功能改進

帖子 ejsoon »

ejime_haha_20260725_22.html
附件
ejime_haha_20260725_22.html.7z
(128.6 KiB) 尚未被下载
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀
帖子: 6345
注册时间: 2022年 11月 18日 17:36
联系:

Re: 尹卂網頁輸入法功能改進

帖子 ejsoon »

順便改進下rime,使之能四碼頂字上屏:

代码: 全选

# haha.schema.yaml
#
schema:
  schema_id: haha
  name: "哈哈倉頡"
  version: "20260726_004325"
  author: "尹卂"
  description: "https://ejsoon.vip/haha"
engine:
  processors:
    - ascii_composer
    - key_binder
    - speller
    - selector
    - punctuator
    - express_editor
  segmentors:
    - ascii_segmentor
    - abc_segmentor
    - punct_segmentor
    - fallback_segmentor
  translators:
    - punct_translator
    - table_translator
switches:
  - name: ascii_mode
    reset: 0
    states: [ 中文, 西文 ]
  - name: ascii_punct
    states: ["。,", ".,"]
translator:
  dictionary: haha
  enable_completion: false
  enable_user_dict: false
  enable_sentence: false
  preedit_format:
    - xform/^([a-z]*)$/\U$1\E/
    - "xlit|ABCDEFGHIJKLMNOPQRSTUVWXYZ|日月金木水火土竹戈十大中一弓人心手口尸廿山女田難卜重|"
  comment_format:
    - "xlit|abcdefghijklmnopqrstuvwxyz~|日月金木水火土竹戈十大中一弓人心手口尸廿山女田難卜重~|"
menu:
  page_size: 9
  alternative_select_keys: "123456789"
key_binder:
  bindings:
    - { accept: semicolon, send: 2, when: has_menu }
    - { accept: apostrophe, send: 3, when: has_menu }
    - { accept: slash, send: 4, when: has_menu }
punctuator:
  full_shape:
    ",": {commit: ","}
    ".": {commit: "。"}
    "/": {commit: "、"}
    "!": {commit: "!"}
    "@": {commit: "•"}
    "^": {commit: "……"}
    "$": {commit: "¥"}
    "_": {commit: "——"}
    "-": {commit: "―"}
    "|": {commit: "︱"}
    "?": {commit: "?"}
    ":": {commit: ":"}
    ";": {commit: ";"}
    "[": {commit: "「"}
    "]": {commit: "」"}
    "{": {commit: "『"}
    "}": {commit: "』"}
    "(": {commit: "("}
    ")": {commit: ")"}
    "\"": {commit: "“”"}
    "'": {commit: "‘’"}
    "<": {commit: "《"}
    ">": {commit: "》"}
  half_shape:
    ",": {commit: ","}
    ".": {commit: "。"}
    "/": {commit: "、"}
    "!": {commit: "!"}
    "@": {commit: "•"}
    "^": {commit: "……"}
    "$": {commit: "¥"}
    "_": {commit: "——"}
    "-": {commit: "―"}
    "|": {commit: "︱"}
    "?": {commit: "?"}
    ":": {commit: ":"}
    ";": {commit: ";"}
    "[": {commit: "「"}
    "]": {commit: "」"}
    "{": {commit: "『"}
    "}": {commit: "』"}
    "(": {commit: "("}
    ")": {commit: ")"}
    "\"": {commit: "“”"}
    "'": {commit: "‘’"}
    "<": {commit: "《"}
    ">": {commit: "》"}
增加「頂字上屏」功能:如果編碼滿四碼時有字在候選區,這時再按下一個編碼,則把候選區的首字上屏,並且這個編碼將成為新的編碼。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀
帖子: 6345
注册时间: 2022年 11月 18日 17:36
联系:

Re: 尹卂網頁輸入法功能改進

帖子 ejsoon »

gemini 3.6 flash

代码: 全选

要實現「編碼滿 4 碼時,再按第 5 個編碼自動將首字上屏,並將新按鍵作為新編碼開頭」的「頂字上屏」功能,需要在 RIME 方案中加入 **`speller`** 配置段落,並設定 **`max_code_length: 4`** 與 **`auto_select: true`**。

修改後的完整配置文件如下:

```yaml
# haha.schema.yaml
#
schema:
  schema_id: haha
  name: "哈哈倉頡"
  version: "20260726_004325"
  author: "尹卂"
  description: "https://ejsoon.vip/haha"

engine:
  processors:
    - ascii_composer
    - key_binder
    - speller
    - selector
    - punctuator
    - express_editor
  segmentors:
    - ascii_segmentor
    - abc_segmentor
    - punct_segmentor
    - fallback_segmentor
  translators:
    - punct_translator
    - table_translator

switches:
  - name: ascii_mode
    reset: 0
    states: [ 中文, 西文 ]
  - name: ascii_punct
    states: ["。,", ".,"]

# --------------------------------------------------
# 新增 speller 配置,實現四碼頂字上屏
# --------------------------------------------------
speller:
  alphabet: zyxwvutsrqponmlkjihgfedcba
  max_code_length: 4   # 設定最大編碼長度為 4 碼
  auto_select: true    # 超過最大長度時,自動上屏當前候選區首字,並將新按鍵轉為新編碼

translator:
  dictionary: haha
  enable_completion: false
  enable_user_dict: false
  enable_sentence: false
  preedit_format:
    - xform/^([a-z]*)$/\U$1\E/
    - "xlit|ABCDEFGHIJKLMNOPQRSTUVWXYZ|日月金木水火土竹戈十大中一弓人心手口尸廿山女田難卜重|"
  comment_format:
    - "xlit|abcdefghijklmnopqrstuvwxyz~|日月金木水火土竹戈十大中一弓人心手口尸廿山女田難卜重~|"

menu:
  page_size: 9
  alternative_select_keys: "123456789"

key_binder:
  bindings:
    - { accept: semicolon, send: 2, when: has_menu }
    - { accept: apostrophe, send: 3, when: has_menu }
    - { accept: slash, send: 4, when: has_menu }

punctuator:
  full_shape:
    ",": {commit: ","}
    ".": {commit: "。"}
    "/": {commit: "、"}
    "!": {commit: "!"}
    "@": {commit: "•"}
    "^": {commit: "……"}
    "$": {commit: "¥"}
    "_": {commit: "——"}
    "-": {commit: "―"}
    "|": {commit: "︱"}
    "?": {commit: "?"}
    ":": {commit: ":"}
    ";": {commit: ";"}
    "[": {commit: "「"}
    "]": {commit: "」"}
    "{": {commit: "『"}
    "}": {commit: "』"}
    "(": {commit: "("}
    ")": {commit: ")"}
    "\"": {commit: "“”"}
    "'": {commit: "‘’"}
    "<": {commit: "《"}
    ">": {commit: "》"}
  half_shape:
    ",": {commit: ","}
    ".": {commit: "。"}
    "/": {commit: "、"}
    "!": {commit: "!"}
    "@": {commit: "•"}
    "^": {commit: "……"}
    "$": {commit: "¥"}
    "_": {commit: "——"}
    "-": {commit: "―"}
    "|": {commit: "︱"}
    "?": {commit: "?"}
    ":": {commit: ":"}
    ";": {commit: ";"}
    "[": {commit: "「"}
    "]": {commit: "」"}
    "{": {commit: "『"}
    "}": {commit: "』"}
    "(": {commit: "("}
    ")": {commit: ")"}
    "\"": {commit: "“”"}
    "'": {commit: "‘’"}
    "<": {commit: "《"}
    ">": {commit: "》"}

```

---

### 修改說明

* **`alphabet`**:定義可接受的字母範圍(`a-z`)。
* **`max_code_length: 4`**:將最大輸入碼長限制為 4 碼。
* **`auto_select: true`**:當已經達到 4 碼且有候選字時,按下下一個字元,系統會自動頂出(上屏)當前的第一個候選字,並把這個新按鍵作為新一輪輸入的開頭。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
一枝独秀
帖子: 6345
注册时间: 2022年 11月 18日 17:36
联系:

Re: 尹卂網頁輸入法功能改進

帖子 ejsoon »

patch:
"preset_keyboards/haha":
ascii_mode: 0
author: "尹卂"
height: 50
name: "哈哈倉頡鍵盤"
width: 10
keys: [{click: Up, width: 25, height: 30}, {click: Down, width: 25, height: 30}, {click: Left, width: 25, height: 30}, {click: Right, width: 25, height: 30}, {click: q, label: "手", long_click: "!"}, {click: w, label: "田", long_click: "@"}, {click: e, label: "水", long_click: "#"}, {click: r, label: "口", long_click: "$"}, {click: t, label: "廿", long_click: "%"}, {click: y, label: "卜", long_click: "^"}, {click: u, label: "山", long_click: "&"}, {click: i, label: "戈", long_click: "*"}, {click: o, label: "人", long_click: "("}, {click: p, label: "心", long_click: ")"}, {width: 5}, {click: a, label: "日", long_click: "`"}, {click: s, label: "尸", long_click: "~"}, {click: d, label: "木", long_click: "-"}, {click: f, label: "火", long_click: "_"}, {click: g, label: "土", long_click: "="}, {click: h, label: "竹", long_click: "+"}, {click: j, label: "十", long_click: ";"}, {click: k, label: "大", long_click: ":"}, {click: l, label: "中", long_click: "'"}, {click: Escape, ascii: Shift_L, width: 15}, {click: z, label: "重", long_click: "\""}, {click: x, label: "難", long_click: "{"}, {click: c, label: "金", long_click: "}"}, {click: v, label: "女", long_click: "|"}, {click: b, label: "月", long_click: "\\"}, {click: n, label: "弓", long_click: "["}, {click: m, label: "一", long_click: "]"}, {click: BackSpace, width: 15}, {click: Mode_switch, width: 15, height: 70}, {click: Keyboard_symbols, height: 70}, {ascii: ",", click: ",", long_click: "<", height: 70}, {click: space, width: 30, height: 70}, {ascii: ".", click: ".", long_click: ">", height: 70}, {ascii: "/", click: "/", long_click: "?", height: 70}, {click: Return, composing: Return1, width: 15, height: 70}]

把「符號」放到方向鍵行的最左邊,把「斜槓」放到方向鍵行的最右邊,之後調整方向鍵及空白鍵的寬度。方向鍵一行的高度調成跟下方的一樣。

gemini 3.6 flash+thinking

代码: 全选

## 修改後的 YAML 配置

已為你完成鍵盤佈局調整,修改細節如下:

---

### 調整項目說明

* **方向鍵行**:
* **最左邊** 加入 **符號鍵** (`Keyboard_symbols`)。
* **最右邊** 加入 **斜槓鍵** (`/`)。
* 四個方向鍵(`Up`、`Down`、`Left`、`Right`)的寬度由 **25** 調整為 **20**,高度由 **30** 統一升為 **70**。


* **底部按鍵列**:
* 移出已拉至上方的 **符號鍵** 與 **斜槓鍵**。
* **空白鍵** (`space`) 寬度由 **30** 增加至 **50**,確保整行總寬度剛好滿格 (100)。



---

### 修改後的 YAML 代碼

```yaml
patch:
  "preset_keyboards/haha":
    ascii_mode: 0
    author: "尹卂"
    height: 50
    name: "哈哈倉頡鍵盤"
    width: 10
    keys: [{click: Keyboard_symbols, height: 70}, {click: Up, width: 20, height: 70}, {click: Down, width: 20, height: 70}, {click: Left, width: 20, height: 70}, {click: Right, width: 20, height: 70}, {ascii: "/", click: "/", long_click: "?", height: 70}, {click: q, label: "手", long_click: "!"}, {click: w, label: "田", long_click: "@"}, {click: e, label: "水", long_click: "#"}, {click: r, label: "口", long_click: "$"}, {click: t, label: "廿", long_click: "%"}, {click: y, label: "卜", long_click: "^"}, {click: u, label: "山", long_click: "&"}, {click: i, label: "戈", long_click: "*"}, {click: o, label: "人", long_click: "("}, {click: p, label: "心", long_click: ")"}, {width: 5}, {click: a, label: "日", long_click: "`"}, {click: s, label: "尸", long_click: "~"}, {click: d, label: "木", long_click: "-"}, {click: f, label: "火", long_click: "_"}, {click: g, label: "土", long_click: "="}, {click: h, label: "竹", long_click: "+"}, {click: j, label: "十", long_click: ";"}, {click: k, label: "大", long_click: ":"}, {click: l, label: "中", long_click: "'"}, {click: Escape, ascii: Shift_L, width: 15}, {click: z, label: "重", long_click: "\""}, {click: x, label: "難", long_click: "{"}, {click: c, label: "金", long_click: "}"}, {click: v, label: "女", long_click: "|"}, {click: b, label: "月", long_click: "\\"}, {click: n, label: "弓", long_click: "["}, {click: m, label: "一", long_click: "]"}, {click: BackSpace, width: 15}, {click: Mode_switch, width: 15, height: 70}, {ascii: ",", click: ",", long_click: "<", height: 70}, {click: space, width: 50, height: 70}, {ascii: ".", click: ".", long_click: ">", height: 70}, {click: Return, composing: Return1, width: 15, height: 70}]

```
https://ejsoon.vip/
弈趣極光:享受思維樂趣
回复
  • 相似主题
    回复总数
    阅读次数
    最新帖子

在线用户

正浏览此版面之用户: 没有注册用户 和 72 访客