Dans une zone de saisie ou contenteditable = true div, comment puis-je modifier une pression de touche pour la lettre "a" pour renvoyer une action-clé pour la lettre "b"? Autrement dit, chaque fois que vous tapez la lettre "a" dans le div, la sortie est en réalité la lettre "b".
Je ne suis pas concerné par une solution qui fonctionne dans IE - juste une qui fonctionne dans Safari, Chrome, et FF.
Dans Chrome, je peux voir qu'un événement de frappe a les propriétés "charCode", "keyCode" et "which", qui reçoivent toutes le numéro d'événement de frappe. Si je déclenche un événement sur un appui-clavier, je peux modifier ces valeurs, mais je ne peux pas déterminer ce qu'il faut renvoyer, de sorte que la clé tapée est différente. Par exemple:
$(window).keypress(function(e){ //$(window) is a jQuery object
e.charCode = 102;
e.which = 102;
e.keyCode = 102;
console.log(e);
return e;
});
Je peux également voir que, avec charCode, qui, et keyCode, il existe également une propriété "originalEvent" qui, à son tour, possède également ces propriétés. Cependant, je n'ai pas été capable de les modifier (j'ai essayé avec des choses comme e.originalEvent.charCode = 102).
Vous ne pouvez pas modifier le caractère ou la clé associé à un événement clé, ni simuler complètement un événement clé. Cependant, vous pouvez gérer vous-même la frappe et insérer manuellement le caractère souhaité au point/curseur d'insertion actuel. J'ai fourni du code pour le faire à plusieurs endroits sur Stack Overflow. Pour un élément contenteditable
:
Voici un exemple de jsFiddle: http://www.jsfiddle.net/Ukkmu/4/
Pour une entrée:
_ { Puis-je changer conditionnellement le caractère saisi dans une entrée lors de la frappe?
affiche un caractère de clavier différent de celui saisi dans Google Chrome
Exemple jsFiddle inter-navigateurs: http://www.jsfiddle.net/EXH2k/6/
IE> = 9 et exemple non-IE jsFiddle: http://www.jsfiddle.net/EXH2k/7/
Eh bien, ce que vous pouvez faire pour un <input>
ou un <textarea>
consiste simplement à vous assurer que la valeur ne contient aucun caractère "a":
$('input.whatever').keypress(function() {
var inp = this;
setTimeout(function() {
inp.value = inp.value.replace(/a/g, 'b');
}, 0);
});
Cette approche ne pourrait probablement pas gérer toutes les astuces que vous pourriez réaliser avec quelque chose qui a vraiment échangé le caractère "pressé", mais je ne connais aucun moyen de le faire.
edit - oh, et la raison pour laquelle j’ai tapé dans cet exemple avec le "correctif" se produisant dans un gestionnaire de dépassement de délai est qu’il s’assure que le navigateur a la possibilité de gérer le comportement natif de l’événement "pression". Lorsque le code du gestionnaire de délai d'attente s'exécute, nous sommes sûrs que la valeur de l'élément aura été mise à jour. Je comprends que le code de la cargaison est un peu culte à ce code.
Mon exemple de solution (changer dans input[type=text]
le caractère ','
en '.'
):
element.addEventListener('keydown', function (event) {
if(event.key === ','){
setTimeout(function() {
event.target.value += '.';
}, 4);
event.preventDefault();
};
Je ne sais pas si c'est faisable "facilement", avec quelque chose comme ça:
$(window).keypress(function(e) {
//Captures 'a' or 'A'
if(e.which == 97 || e.which == 65)
{
//Simulate a keypress in a specific field
}
});
Je sais que jQuery a un plug-in de simulation pour simuler des événements de pression de touche, etc., jQuery Simulate . Cela vaut peut-être la peine d’examiner - peut-être aussi un type de jQuery Trigger () event.
Voici un exemple sans utiliser aucune bibliothèque
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">