Changing the keypress

后端 未结 6 1130
北荒
北荒 2020-11-27 06:16

In an input box or contenteditable=true div, how can I modify a keypress for the letter \"a\" to return a keybress for the letter \"b\"? I.e., every time you type the letter

相关标签:
6条回答
  • 2020-11-27 06:37

    Well what you could do for an <input> or <textarea> is just make sure that the value doesn't have any "a" characters in it:

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

    This approach probably couldn't handle all the possible tricks you could pull with something that really swapped out the "pressed" character, but I don't know any way to actually do that.

    edit — oh, and the reason that I typed in that example with the "fixup" happening in a timeout handler is that it makes sure that the browser has the opportunity to handle the native behavior for the "keypress" event. When the timeout handler code runs, we're sure that the value of the element will have been updated. There's a touch of the cargo cult to this code, I realize.

    0 讨论(0)
  • 2020-11-27 06:37

    Here is an example without using any libraries

    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 讨论(0)
  • 2020-11-27 06:41

    You can't change the character or key associated with a key event, or fully simulate a key event. However, you can handle the keypress yourself and manually insert the character you want at the current insertion point/caret. I've provided code to do this in a number of places on Stack Overflow. For a contenteditable element:

    • Need to set cursor position to the end of a contentEditable div, issue with selection and range objects

    Here's a jsFiddle example: http://www.jsfiddle.net/Ukkmu/4/

    For an input:

    • Can I conditionally change the character entered into an input on keypress?

    • show different keyboard character from the typed one in google chrome

    Cross-browser jsFiddle example: http://www.jsfiddle.net/EXH2k/6/

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

    0 讨论(0)
  • 2020-11-27 06:43

    My solution example (change in input[type=text] the character ',' to '.'):

    element.addEventListener('keydown', function (event) {
    if(event.key === ','){
      setTimeout(function() {
        event.target.value += '.';
      }, 4);
      event.preventDefault();
    };
    
    0 讨论(0)
  • 2020-11-27 06:56

    Here a simple example to replace , to . using 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 讨论(0)
  • 2020-11-27 06:57

    I'm not sure if this is "easily" do-able, with something like this:

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

    I do know that jQuery has a simulate plug-in to simulate keypress events etc, jQuery Simulate. It might be worth looking into - also possibly some type of jQuery Trigger() event.

    0 讨论(0)
提交回复
热议问题