Почти во всех браузерах есть возможность переключать фокус с помощью клавиши Tab.
Но своенравные пользователи настоятельно требуют, чтобы была функция клавиши Enter для переключения фокуса.
Для того, чтобы доставить деньги онлайн, мы должны были принять потребности клиента без каких-либо принципов.
В предыдущем поколении у большинства из них была такая рабочая привычка. Привыкайте называть сохранение как редактирование и привыкайте заменять Tab на Enter. Это результат отравления Microsoft Excel.
Сначала я думал, что эта функция очень проста, не более чем перенос функции клавиши Enter на клавишу Tab, и проблема может быть решена за считанные минуты.
Может быть трудно сразу появиться, я обнаружил, что эта дорога - это тупик.
el.click()Вы можете вызвать событие клики или использоватьdispatchEvent.但是键盘和鼠标事件却不行。
Итак, если вы хотите, чтобы фокус срабатывал не с помощью переключателя клавиши Tab,focusПочти единственный выбор.
Реализуйте клавишу Enter для переключения фокуса на собственных страницах.
Проект основан на vue и element-ui, чтобы сначала прояснить идеи реализации, отложите их на время и найдите ответ на нативной странице.
Ниже приведена собственная html-страница.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Demo</title>
</head>
<body>
<form>
<input placeholder="姓名" />
<input placeholder="性别" />
<input placeholder="年龄" />
</form>
</body>
</html>
Дальше будет реализована клавиша Enter для переключения фокуса, я думал гребенка следующая:
- Прослушайте событие нажатия клавиши Enter.
- Получить текущий сфокусированный элемент.
- Получите следующий элемент, который будет сфокусирован.
- Переключить фокус.
Идея есть, и реализовать ее очень просто.
1. Прослушайте событие нажатия клавиши Enter
Добавьте тег script в документ и напишите следующий код.
function enterCallback(e) {
if (e.keyCode === 13) {
// 按下回车后的逻辑
}
}
window.addEventListener("keydown", enterCallback);
обращать внимание,enterCallbackВыньте его отдельно и используйте для выхода из события прослушивателя.
Наиболее распространенный способ прослушивания событий нажатия клавиш — использовать делегирование событий для привязки событий кwindowна объекте. По сравнению с методом привязки события к каждому элементу самым большим преимуществом этого метода является экономия памяти и более высокая производительность.
Есть много способов определить, какая клавиша нажата, например,e.key,e.codeилиe.keyCodeи так далее. Но в большинстве случаев рекомендуется использоватьe.keyCode.下面是一张来自网络的keyCodeповерхность.
2. Получить текущий сфокусированный элемент
常见的有两种方式。 Первыйe.targetВторойdocument.activeElement.这种情况下,个人更推荐使用第二种。
function enterCallback(e) {
if (e.keyCode === 13) {
let activeEl = document.activeElement;
}
}
3. Получить следующий элемент для фокусировки
Этот шаг также проще. использоватьel.nextElementSiblingДоступен API.
function enterCallback(e) {
if (e.keyCode === 13) {
let activeEl = document.activeElement;
let nextEl = activeEl.nextElementSibling;
}
}
4. Переключить фокус
вызов переключения фокусаfocusможет быть достигнут.
function enterCallback(e) {
if (e.keyCode === 13) {
let activeEl = document.activeElement;
let nextEl = activeEl.nextElementSibling;
nextEl && nextEl.focus();
}
}
Пока реализовано самое простое Demo, давайте посмотрим на реальную ситуацию в проекте.
Реализуйте клавишу Enter для переключения фокуса в проекте element-ui.
Из-за использования разработки компонентов и таких факторов, как стиль, узел dom не так прост, как нативная демонстрация, написанная выше, и реальная ситуация представляет собой многоуровневую вложенность. Ниже приведена фактическая сгенерированная структура кода.
<div
class="el-form-item el-form-item--small"
style="margin-bottom: 0vh; width: 25%; display: inline-block;"
>
<label for="pactcode" class="el-form-item__label" style="width: 130px;"
>协议号</label
>
<div class="el-form-item__content" style="margin-left: 130px;">
<div class="el-input el-input--small">
<!---->
<input
type="text"
autocomplete="off"
id="el-input"
placeholder="未填写协议号"
class="el-input__inner"
/>
<!---->
</div>
</div>
</div>
Можно видеть, что если каждое поле ввода представляет собой вложенную структуру такого типа, описанный выше метод не может быть решен напрямую. потому чтоnextElementSiblingAPI может найти только следующий родственный элемент, а здесь ввод явно не может найти следующий родственный элемент.
Идея состоит в том, чтобы искать внешний слой с помощью поиска с возвратом, пока вы не найдете имя класса, содержащееel-form-itemа такжеel-form-item--smallЭлемент-предок элемента-предка, а затем найдите имя класса из следующего родственного элемента этого элемента-предка.el-input__innerВходные элементы.
Итак, чтобы написать две функции, а именно для поиска элементов-предковfindFormItemfindInput.
найтиформитем:
function findFormItem(el) {
const parent = el.parentElement;
if (!parent) return document.body;
if (
parent.className.includes("el-form-item") &&
parent.className.includes("el-form-item--small")
) {
return parent;
}
return findFormItem(parent);
}
найтиВвод:
function findInput(container) {
let nextEl = container.nextElementSibling;
if (!nextEl) return;
let input = nextEl.querySelector("input");
while (input.id === "el-select") {
nextEl = nextEl.nextElementSibling;
if (!nextEl) return;
input = nextEl.querySelector("input");
}
if (input.className.includes("el-input__inner")) return input;
}
С помощью этих двух функций очень просто переключить фокус с помощью Enter. Необходимо выполнить всего две строки кода.
const container = findFormItem(document.activeElement);
findInput(container) && findInput(container).focus();
Полный код выглядит так.
существуетmethodsТри метода объявлены в .
methods: {
addEnterListener() {
if (window.__completeEnterBind__) return;
window.addEventListener("keydown", this.enterCallback);
window.__completeEnterBind__ = true;
},
removeEnterListener() {
window.removeEventListener("keydown", this.enterCallback);
window.__completeEnterBind__ = false;
},
enterCallback(e) {
function findFormItem(el) {
const parent = el.parentElement;
if (!parent) return document.body;
if (
parent.className.includes("el-form-item") &&
parent.className.includes("el-form-item--small")
) {
return parent;
}
return findFormItem(parent);
}
function findInput(container) {
let nextEl = container.nextElementSibling;
if (!nextEl) return;
let input = nextEl.querySelector("input");
while (input.id === "el-select") {
nextEl = nextEl.nextElementSibling;
if (!nextEl) return;
input = nextEl.querySelector("input");
}
if (input.className.includes("el-input__inner")) return input;
}
if (e.keyCode === 13) {
const container = findFormItem(document.activeElement);
findInput(container) && findInput(container).focus();
}
}
}
затем вmountedДобавить прослушиватель возврата каретки в и вdestroyУберите клавишу Enter из прослушивания.
mounted() {
this.addEnterListener();
},
destroy() {
this.removeEnterListener();
},
Следует отметить, что элемент находится в форме страницы с несколькими вкладками, и компонент формы может отображаться несколько раз, поэтому, добавляя окно к объекту__completeEnterBind__поле, чтобы обеспечить правильную привязку событий возврата каретки и перевода строки.
Таким образом, они выполнили конкретные потребности пользователя, от средств проекта, чтобы стать на шаг ближе.
Оригинальный адрес:У-у-у, Лу Чжэньцянь.