vanilla javascript :拦截输入键并更改键值

vanilla javascript : intercept key on input and change key value

我想截取一个输入中键入的键并将其更改为其他键。

例如,我想模拟每次按下一个键时输入一个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; 因为当input中已经有文本,光标不在文本末尾或者用户用鼠标选择了所有文本时,如果在input末尾添加文本,它不会自然地起作用

你能帮帮我吗?

通过从导致同一事件的事件中调度一个事件,您将创建一个无限循环,该循环将导致 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 取自这个答案:

You can change that to a normal function if you don't want to extend the built in's prototype