預設 Enter 鍵在表單中會觸發提交。某些資料密集型表單 (如會計記帳、庫存登錄) 希望 Enter 鍵像 Tab 鍵一樣移動到下一個欄位,提升錄入效率。
<script>
function cgo(obj, element, method) {
// obj: form 物件, element: 當前元素 name, method: 'prv' 上一個 / 其他 下一個
for (var tmpa = 0; tmpa < obj.length; tmpa++) {
if (obj[tmpa].name == element) {
id = tmpa;
}
}
if (method == "prv") {
obj[id-1].focus();
} else {
obj[id+1].focus();
}
}
</script>
<form name="form1">
<input type="text" name="a1" onkeyup="cgo(this.form, this.name, '')">
<input type="text" name="a2" onkeyup="cgo(this.form, this.name, '')">
<input type="text" name="a3" onkeyup="cgo(this.form, this.name, '')">
</form>
onkeyup 會在彈起時觸發,含 Enter、字母、Backspace 等所有鍵,導致任何輸入都跳轉焦點。event.keyCode === 13 (Enter)。id 變數未宣告 (隱性全域變數)。<script>
function handleEnterTab(event, form, currentName, direction) {
// direction: 'next' (預設) 或 'prev' (Shift+Enter)
if (event.key !== 'Enter') return; // 僅處理 Enter
var elements = [];
// 收集所有可聚焦的表單元素 (排除隱藏、禁用、readonly)
for (var i = 0; i < form.elements.length; i++) {
var el = form.elements[i];
if (el.type !== 'hidden' && !el.disabled && !el.readOnly &&
['text', 'textarea', 'select-one', 'select-multiple', 'password', 'email', 'number', 'date'].includes(el.type)) {
elements.push(el);
}
}
var idx = elements.findIndex(function(el) { return el.name === currentName; });
if (idx === -1) return;
var nextIdx = direction === 'prev' ? idx - 1 : idx + 1;
if (nextIdx >= 0 && nextIdx < elements.length) {
event.preventDefault(); // 阻止表單提交
elements[nextIdx].focus();
}
// 邊界不處理:第一個欄位 Shift+Enter、最後一個欄位 Enter 維持原狀
}
// 綁定方式:建議使用事件委派
document.addEventListener('DOMContentLoaded', function() {
var forms = document.querySelectorAll('form[data-enter-tab]');
forms.forEach(function(form) {
form.addEventListener('keydown', function(e) {
var target = e.target;
if (target.form !== form) return;
var dir = e.shiftKey ? 'prev' : 'next';
handleEnterTab(e, form, target.name, dir);
});
});
});
</script>
<form data-enter-tab>
<input type="text" name="field1" placeholder="欄位 1">
<input type="text" name="field2" placeholder="欄位 2">
<textarea name="field3" placeholder="欄位 3 (多行)"></textarea>
<select name="field4"><option>選項</option></select>
<button type="submit">送出</button> <!-- 最後按 Enter 仍會提交 -->
</form>
| 情境 | 處理建議 |
|---|---|
多行文字區域 <textarea> | 通常保留 Enter 換行功能,可加 data-enter-tab="false" 排除 |
| 按鈕/提交鈕 | 最後一個輸入框 Enter 應提交表單,不跳轉 |
| 動態新增欄位 | 事件委派自動涵蓋新元素,無需重新綁定 |
| 無障礙存取 | 確保 Tab 順序符合邏輯 (tabindex)、螢幕閱讀器可預測行為 |
| 行動裝置 | 虛擬鍵盤「下一個」/「完成」鍵原生支援欄位跳轉,無需此腳本 |
@keydown.enter.prevent="focusNext($event)" 配合 ref 陣列管理焦點。onKeyDown={e => e.key==='Enter' && focusNext(e)},使用 useRef 陣列。@keydown.enter.window="focusNext($event)" 輕量實作。Enter 轉 Tab 是特定業務場景的體驗優化,實作時務必精準判斷鍵碼、保護邊界、不干擾原生表單提交與多行輸入,並考慮無障礙與行動裝置差異。