Изменение нажатия клавиши
В поле ввода или contenteditable = true div, как я могу изменить нажатие клавиши для буквы "a", чтобы вернуть keybress для буквы "b"? I.e., каждый раз, когда вы вводите букву "a" в div, вывод на самом деле является буквой "b".
Я не занимаюсь решением, которое работает в IE, - это тот, который работает в Safari, Chrome и FF.
В Chrome я вижу, что событие keypress имеет свойства "charCode", "keyCode" и "which", которым присваивается номер события нажатия клавиши. Если я запускаю событие при нажатии клавиши, я могу изменить эти значения, но я не могу понять, что вернуть, чтобы фактический ключ, который набрал, был другим. Например:
$(window).keypress(function(e){ //$(window) is a jQuery object
e.charCode = 102;
e.which = 102;
e.keyCode = 102;
console.log(e);
return e;
});
Я также вижу, что наряду с charCode, который и keyCode, также имеет свойство "originalEvent", которое также имеет эти свойства. Однако я не смог их изменить (я пробовал такие вещи, как e.originalEvent.charCode = 102).
Ответы
Ответ 1
Вы не можете изменить символ или ключ, связанный с ключевым событием, или полностью имитировать ключевое событие. Тем не менее, вы можете обрабатывать нажатия клавиш самостоятельно и вручную вставлять символ, который вы хотите, в текущую точку вставки/каретку. Я предоставил код, чтобы сделать это в нескольких местах в Stack Overflow. Для элемента contenteditable
:
Вот пример jsFiddle: http://www.jsfiddle.net/Ukkmu/4/
Для ввода:
Пример кросс-браузера jsFiddle: http://www.jsfiddle.net/EXH2k/6/
IE >= 9 и не-IE jsFiddle пример: http://www.jsfiddle.net/EXH2k/7/
Ответ 2
Хорошо, что вы могли бы сделать для <input>
или <textarea>
, просто убедитесь, что в нем нет никаких "a" символов:
$('input.whatever').keypress(function() {
var inp = this;
setTimeout(function() {
inp.value = inp.value.replace(/a/g, 'b');
}, 0);
});
Этот подход, вероятно, не мог справиться со всеми возможными трюками, которые вы могли бы вытащить, с чем-то, что действительно заменило "нажатый" символ, но я не знаю, как это сделать на самом деле.
edit — о, и причина, по которой я ввел этот пример с "исправлением", происходящим в обработчике тайм-аута, заключается в том, что он гарантирует, что браузер имеет возможность обрабатывать собственное поведение для события "keypress". Когда выполняется код обработчика тайм-аута, мы уверены, что значение элемента будет обновлено. Я понимаю, что прикосновение культа груза к этому кодексу.
Ответ 3
Пример моего решения (изменение input[type=text]
символа ','
на '.'
):
element.addEventListener('keydown', function (event) {
if(event.key === ','){
setTimeout(function() {
event.target.value += '.';
}, 4);
event.preventDefault();
};
Ответ 4
Я не уверен, что это "легко" сделать, с чем-то вроде этого:
$(window).keypress(function(e) {
//Captures 'a' or 'A'
if(e.which == 97 || e.which == 65)
{
//Simulate a keypress in a specific field
}
});
Я знаю, что jQuery имеет симулирующий плагин для имитации событий нажатия клавиш и т.д. jQuery Simulate. Возможно, стоит посмотреть - также возможно какой-то тип события jQuery Trigger().
Ответ 5
Вот пример без использования каких-либо библиотек
const input = document.querySelector('input')
// this is the order of events into an input
input.addEventListener('focus', onFocus)
input.addEventListener('keydown', keyDown)
input.addEventListener('keypress', keyPress)
input.addEventListener('input', onInput)
input.addEventListener('keyup', keyUp)
input.addEventListener('change', onChange)
input.addEventListener('blur', onBlur)
function onFocus (event) { info(event) }
function keyDown (event) { info(event) }
function keyPress (event) {
info(event)
// this 2 calls will stop 'input' and 'change' events
event.preventDefault();
event.stopPropagation();
// get current props
const target = event.target
const start = target.selectionStart;
const end = target.selectionEnd;
const val = target.value;
// get some char based on event
const char = getChar(event);
// create new value
const value = val.slice(0, start) + char + val.slice(end);
// first attemp to set value
// (doesn't work in react because value setter is overrided)
// target.value = value
// second attemp to set value, get native setter
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype,
"value"
).set;
nativeInputValueSetter.call(target, value);
// change cursor position
target.selectionStart = target.selectionEnd = start + 1;
// dispatch 'input' again
const newEvent = new InputEvent('input', {
bubbles: true,
inputType: 'insertText',
data: char
})
event.target.dispatchEvent(newEvent);
}
function keyUp (event) { info(event) }
function onInput (event) { info(event) }
function onChange (event) { info(event) }
function onBlur (event) {
// dispatch 'change' again
const newEvent = new Event('change', { bubbles: true })
event.target.dispatchEvent(newEvent);
info(event)
}
function info (event) { console.log(event.type) }
function getChar(event) {
// will show X if letter, will show Y if Digit, otherwise Z
return event.code.startsWith('Key')
? 'X'
: event.code.startsWith('Digit')
? 'Y'
: 'Z'
}
<input type="text">
Ответ 6
Вот простой пример для замены ,
чтобы .
используя Vanilla JavaScript
// change ',' to '.'
document.getElementById('only_float').addEventListener('keypress', function(e){
if (e.key === ','){
// get old value
var start = e.target.selectionStart;
var end = e.target.selectionEnd;
var oldValue = e.target.value;
// replace point and change input value
var newValue = oldValue.slice(0, start) + '.' + oldValue.slice(end)
e.target.value = newValue;
// replace cursor
e.target.selectionStart = e.target.selectionEnd = start + 1;
e.preventDefault();
}
})
<input type="text" id="only_float" />