vanilla javascript: перехватить ключ при вводе и изменить значение ключа - PullRequest
0 голосов
/ 30 июня 2018

Я хочу перехватить клавиши, введенные на одном входе, и заменить их на другие.

Например, я хочу имитировать ввод 1 при каждом нажатии клавиши.

Я думал что-то вроде этого:

           //this example does not work, it will trigger an endless loop

            Array.from(document.querySelectorAll('.onlyOne')).forEach(input =>
                               input.addEventListener('keydown', (event) => {      
                                event.preventDefault();
                                event.srcElement.dispatchEvent(new KeyboardEvent('keydown', { 'key': 49 }));

                            });
                        }
                    );

Я не могу просто добавить 1 с event.target.value += 1; причина, когда во входном файле уже есть текст, а курсор находится не в конце текста, или пользователь выделил весь текст мышью, он не будет действовать естественным образом, если текст будет добавлен в конце ввода

Не могли бы вы помочь мне, пожалуйста?

1 Ответ

0 голосов
/ 30 июня 2018

Отправляя событие изнутри события, которое вызывает то же событие, вы создаете бесконечный цикл, который вызовет Range Error: Maximum call stack size exceeded.

Вместо события просто добавьте 1 туда, где находится курсор на каждой клавише.

Array.from(document.querySelectorAll('.onlyOne')).forEach(input =>
  input.addEventListener('keydown', (event) => {
    event.preventDefault();
    event.target.insertAtCaret('1');
}));


HTMLInputElement.prototype.insertAtCaret = function (text) {
  text = text || '';
  if (document.selection) {
    // IE
    this.focus();
    var sel = document.selection.createRange();
    sel.text = text;
  } else if (this.selectionStart || this.selectionStart === 0) {
    // Others
    var startPos = this.selectionStart;
    var endPos = this.selectionEnd;
    this.value = this.value.substring(0, startPos) +
      text +
      this.value.substring(endPos, this.value.length);
    this.selectionStart = startPos + text.length;
    this.selectionEnd = startPos + text.length;
  } else {
    this.value += text;
  }
};
<input class='onlyOne' value="foo">

HTMLInputElement.prototype.insertAtCaret взят из этого ответа: https://stackoverflow.com/a/19961519/3993662

Вы можете изменить это на обычную функцию, если вы не хотите расширять встроенный прототип .

...