Я работаю над компонентом в приложении vue, которое принимает код доступа, состоящий из 8 цифр, каждая цифра имеет свой собственный ввод при вводе символа, он должен перейти к следующему вводу, если пользователь удаляет символ, если он может, фокус должен перейти к предыдущему брату, если пользователь нажимает левую или правую клавишу, фокус должен перемещаться вместе с нажатием клавиши. На данный момент происходит то, что события @input и @keydown запускаются, поэтому, если пользователь нажимает влево, а предыдущий брат уже имеет контент, он перемещает фокус обратно вправо.
Вот мой код,
<div class="code">
<input autofocus type="text" maxlength="1" class="passcode__box" @input="handleInput" @keydown="handleKeyDown"/>
<input type="text" class="passcode__box" maxlength="1" @input="handleInput" @keydown="handleKeyDown"/>
<input type="text" class="passcode__box" maxlength="1" @keyup="handleInput" @keydown="handleKeyDown"/>
<input type="text" class="passcode__box" maxlength="1" @keyup="handleInput" @keydown="handleKeyDown"/>
<input type="text" class="passcode__box" maxlength="1" @keyup="handleInput" @keydown="handleKeyDown"/>
<input type="text" class="passcode__box" maxlength="1" @keyup="handleInput" @keydown="handleKeyDown"/>
<input type="text" class="passcode__box" maxlength="1" @keyup="handleInput" @keydown="handleKeyDown"/>
<input type="text" class="passcode__box" maxlength="1" @keyup="handleInput" @keydown="handleKeyDown"/>
</div>
И 2 метода,
handleInput(event) {
const value = event.target.value;
const nextElement = event.target.nextElementSibling;
if (value === "" || !nextElement) {
return;
}
nextElement.focus();
},
handleKeyDown(event) {
console.log('handleKeyDown');
//Right arrow key
if(event.keyCode == 39) {
event.target.nextElementSibling.focus();
}
//Left arrow key
if(event.keyCode == 37) {
event.target.previousElementSibling.focus();
}
//Backspace key - cmd
if(event.keyCode == 8) { //backspace
if(event.target.value === '') {
event.target.previousElementSibling.focus();
return;
}
event.target.value = '';
}
}
Вот пример компонента, который странным образом использует тот же код введите здесь описание ссылки
1 ответ
Я предполагаю, что проблема в событиях @keyup
, потому что @keyup
испускается после @input
. Подробнее о KeyboardEvents и их последовательностях можно прочитать в этой статье MDN.
В любом случае, я позволил себе переписать/рефакторинг кода, который вы предоставили, и представил пару JS-махинаций. Хотя идея та же. Существует рабочий пример в CodeSandbox.
Надеюсь, это помогло!
<template>
<div class="passcode">
<template v-for="index in inputs">
<input
type="text"
class="passcode__box"
:key="index"
:maxlength="maxlength"
@keydown="onKeydown"
@input="onInput"
>
</template>
</div>
</template>
<script>
export const KeyCodes = {
RIGHT_ARROW: 39,
LEFT_ARROW: 37,
BACKSPACE: 8
};
export default {
name: "Passcode",
props: {
inputs: {
type: Number,
default: 4
},
maxlength: {
type: Number,
default: 1
}
},
methods: {
/**
* Moves focus between siblings and handles `Backspace`.
*
* @param {KeyboardEvent} event
*/
onKeydown(event) {
const target = event.target;
const next = target.nextElementSibling;
const prev = target.previousElementSibling;
switch (event.keyCode) {
case KeyCodes.RIGHT_ARROW:
next && next.focus();
break;
case KeyCodes.LEFT_ARROW:
prev && prev.focus();
break;
case KeyCodes.BACKSPACE:
if (target.value.length) {
target.value = "";
return;
}
setTimeout(() => prev && prev.focus());
break;
default:
break;
}
},
/**
* Handles printable characters and moves focus
* to the next <input> sibling if it's present.
*
* @param {KeyboardEvent} event
*/
onInput(event) {
const value = event.target.value;
const next = event.target.nextElementSibling;
if (!value.length || !next) {
return;
}
next.focus();
}
}
};
</script>
Похожие вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript/JS) и его различных диалектах/реализациях (кроме ActionScript). Имейте в виду, что JavaScript — это НЕ то же самое, что Java! Включите все ярлыки, относящиеся к вашему вопросу; например, [node.js], [jQuery], [JSON], [ReactJS], [angular], [ember.js], [vue.js], [typescript], [svelte] и т. д.