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。
我想截取一个输入中键入的键并将其更改为其他键。
例如,我想模拟每次按下一个键时输入一个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。