2

Look at this very simple jsfiddle: https://jsfiddle.net/gq9jga4q/33/

<input type="text" id="kbdhook" />

<div id="result" >1: </div>

<div id="result2" >2: </div>

<div id="result3" >3: </div>

$('#kbdhook').keyup(function(event) {
      var current = $('#kbdhook').val();
      if (current !== '' && current !== '\n') {
        var c, l;
        for (l = 0; l < current.length; l++) {
          c = current[l];
          $("#result").html($("#result").html() + c);
        }

        $("#result2").html($("#result2").html() + " " + $('#kbdhook').val());
        $('#kbdhook').val('');
        $("#result3").html($("#result3").html() + " " + $('#kbdhook').val());
      }
  });

My goal is to be able to call a function for every keys typed in an input element.

I'm subscribing to the keyup event and for every letters in it I append them to the document and then clear the text input in order to restart anew the next time.

The #result div is the wanted output that's going to be sent to an external library.

#result2 is used to show that sometimes when you type fast there's multiple letters getting registered in a single keyup event (that's ok).

#result3 is used to show that after clearing the input it is indeed well cleared.

This works perfectly on desktop (IE/Chrome/Firefox) and on iPhone (Safari/Chrome) and also on Android (Firefox). But Chrome on Android give a different behaviour.

Every time the keyup event is triggered, the result of $('#kbdhook').val() is the value as if the "clearing" $('#kbdhook').val(''); would not have happened. But it did, because #result3 is always blank.

Why such a difference in behaviour between the different browsers, and how could I fix my problem?

Dunge
  • 532
  • 3
  • 19
  • Thanks for the reply, but I don't understand it. What is the goal of "if(onclick)" (that always returns false)? Are you trying to see if the onclick event is defined, or referencing some variable? Also, the touchend event fire only when I re-tap on the text input after writing text, and not after each letter typed. – Dunge Feb 28 '18 at 03:44
  • Sorry but `typeof onclick`seems defined both on mobile and on desktop on all browsers, and you probably inversed the condition you meant in the comment above. Most importantly, `touchend` does not seems to be a proper replacement fixing this issue since it does not fire at each letter pressed. – Dunge Feb 28 '18 at 05:58
  • Sorry about the misinformation. I would use `if(onmousemove){ /* assume regular events can be used */ } else{ /* assume you need touch events */ }`. That, however, doesn't look like your problem. If you do `$('#kbdhook').val('')` before `$('#kbdhook').val()`, `$('#result3').html()+' '+$('#kbdhook').val()` would be `'3: '`. – StackSlave Feb 28 '18 at 23:19

1 Answers1

1

I ended up with a mix of Glauber Borges answer on this thread and mine. I had to use event.preventdefault() in his keydown handler when it was special codes (arrow keys, delete, backspace, return) otherwise it screw his result when the caret is not at the end.

This worked fine for Android Chrome, but then Android Firefox was now the one getting duplicate text. So just like I was doing previously I also added a call to .val(''); to clear after appending the text difference in the input handler and it seems to work on every platforms now.

Google really should create a better standard for text input events, this lack of common behaviour between browsers (and the 229 keycode) is awful.

Dunge
  • 532
  • 3
  • 19