Изменение нажатия клавиши - PullRequest
23 голосов
/ 05 января 2011

В поле ввода или contenteditable = true div, как я могу изменить нажатие клавиши для буквы "a", чтобы она возвращала нажатие клавиши для буквы "b"? То есть, каждый раз, когда вы вводите букву «a» в div, на самом деле выводится буква «b».

Меня не интересует решение, которое работает в IE - только то, которое работает в Safari, Chrome и FF.

В Chrome я вижу, что событие нажатия клавиши имеет свойства "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).

Ответы [ 6 ]

28 голосов
/ 05 января 2011

Вы не можете изменить символ или клавишу, связанные с ключевым событием, или полностью смоделировать ключевое событие. Тем не менее, вы можете справиться с нажатием клавиши самостоятельно и вручную вставить нужный символ в текущей точке вставки / каретке. Я предоставил код для этого в нескольких местах переполнения стека. Для элемента contenteditable:

Вот пример jsFiddle: http://www.jsfiddle.net/Ukkmu/4/

Для входа:

Кросс-браузерный пример jsFiddle: http://www.jsfiddle.net/EXH2k/6/

IE> = 9 и пример jsFiddle без IE: http://www.jsfiddle.net/EXH2k/7/

1 голос
/ 12 декабря 2016

Пример моего решения (изменить input[type=text] символ ',' на '.'):

element.addEventListener('keydown', function (event) {
if(event.key === ','){
  setTimeout(function() {
    event.target.value += '.';
  }, 4);
  event.preventDefault();
};
1 голос
/ 05 января 2011

Что вы могли бы сделать для <input> или <textarea>, просто убедитесь, что в значении нет символов "a":

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

Этот подход, вероятно, не справился бы со всеми возможными уловками, которые вы могли бы применить с чем-то, что действительно заменяло бы "нажатого" персонажа, но я не знаю, как на самом деле это сделать.

edit & mdash; о, и причина, по которой я набрал в этом примере, что «исправление» происходит в обработчике тайм-аута, заключается в том, что он обеспечивает браузеру возможность обрабатывать нативное поведение для события «нажатие клавиши». Когда выполняется код обработчика тайм-аута, мы уверены, что значение элемента будет обновлено. Я понимаю, что в этом коде есть прикосновение культа груза.

0 голосов
/ 12 июня 2019

Вот простой пример замены , на . с использованием 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" />
0 голосов
/ 17 июля 2018

Вот пример без использования каких-либо библиотек

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">
0 голосов
/ 05 января 2011

Я не уверен, что это "легко" выполнимо, с чем-то вроде этого:

$(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 () .

...