javascript - onkeyup jquery event




Modifica della pressione del tasto (4)

In una casella di input o contenteditable = true div, come posso modificare una pressione di un tasto per la lettera "a" per restituire una chiave per la lettera "b"? Ad esempio, ogni volta che si digita la lettera "a" nel div, l'output è in realtà la lettera "b".

Non mi preoccupo di una soluzione che funziona in IE - solo una che funzioni in Safari, Chrome e FF.

In Chrome, posso vedere che un evento keypress ha le proprietà "charCode", "keyCode" e "which", a cui viene assegnato il numero di evento keypress. Se si attiva un evento su un tasto, posso modificare questi valori, ma non riesco a capire cosa restituire in modo che la chiave effettiva che viene digitata sia diversa. Per esempio:

$(window).keypress(function(e){  //$(window) is a jQuery object
    e.charCode = 102;
    e.which = 102;
    e.keyCode = 102;
    console.log(e);
    return e;
});

Posso anche vedere che insieme a charCode, which e keyCode, esiste anche una proprietà "originalEvent" che a sua volta ha anche queste proprietà. Tuttavia, non sono stato in grado di modificarli (ho provato con cose come e.originalEvent.charCode = 102).


Beh, quello che potresti fare per un <input> o <textarea> è solo assicurarti che il valore non abbia caratteri "a" in esso:

$('input.whatever').keypress(function() {
  var inp = this;
  setTimeout(function() {
    inp.value = inp.value.replace(/a/g, 'b');
  }, 0);
});

Questo approccio probabilmente non è stato in grado di gestire tutti i possibili trucchi che potresti ottenere con qualcosa che ha veramente scambiato il carattere "premuto", ma non conosco alcun modo per farlo davvero.

edit - oh, e il motivo per cui ho digitato quell'esempio con la "fixup" che si verifica in un gestore di timeout è che si assicura che il browser abbia l'opportunità di gestire il comportamento nativo per l'evento "keypress". Quando viene eseguito il codice del gestore di timeout, siamo sicuri che il valore dell'elemento sarà stato aggiornato. C'è un tocco del culto del carico in questo codice, me ne rendo conto.


Ecco un esempio senza utilizzare alcuna libreria

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">


Non è possibile modificare il carattere o la chiave associata a un evento chiave o simulare completamente un evento chiave. Tuttavia, è possibile gestire personalmente la pressione del tasto e inserire manualmente il carattere desiderato nell'attuale punto di inserimento / cursore. Ho fornito il codice per farlo in un numero di punti su . Per un elemento contenteditable :

Ecco un esempio di jsFiddle: http://www.jsfiddle.net/Ukkmu/4/

Per un input:

Esempio cross-browser jsFiddle: http://www.jsfiddle.net/EXH2k/6/

IE> = 9 e non-IE Esempio jsFiddle: http://www.jsfiddle.net/EXH2k/7/


Non sono sicuro che sia "facilmente" fattibile, con qualcosa del genere:

$(window).keypress(function(e) { 
    //Captures 'a' or 'A'
    if(e.which == 97 || e.which == 65)
    {
        //Simulate a keypress in a specific field  
    }
});

So che jQuery ha un plug-in simulato per simulare eventi di keypress ecc, jQuery Simulate . Potrebbe valere la pena esaminare - anche possibilmente qualche tipo di evento jQuery Trigger() .







keydown