Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid keydown delay with jQuery?

GOAL:

When a user types character in a text box, make a button appear. When the user clears the text box using the backspace key but holds down that key for a few extra seconds, hide the button instantly.

ISSUE:

If a user types in a single character, and uses the backspace to remove it—by holding down the backspace key a few extra seconds—there is a delay before the button is hidden. This only happens when the user typed only one character and then held down the the backspace key without letting go. If instead the user typed multiple characters, and then held down the backspace key until the textbox was empty, there was no delay in hiding the button.

<input type="text" id="tbox"></text>
<button type="button" id="btn"  style="display:none;">push me</button>

$('#tbox').on('keydown keypress keyup',function(){
    if($('#tbox').val() !== '') {
        $('#btn').css({'display':'block'});
    } else {
        $('#btn').css({'display':'none'});
    }
});

JSFIDDLE:

http://jsfiddle.net/odkut0dh/

like image 260
brooklynsweb Avatar asked Aug 06 '15 03:08

brooklynsweb


2 Answers

A little walkthrough the situation :

Assuming that <input> value is "x" and you type backspace :
- When the keydown event fires the input's value is still "x".
- When the keypress fires, it still "x".
If you don't release the key :
__ keydown fires again, after some delay, depending on os I guess value is now "".
__ keypress fires again, value is still "".
__ When you release the key, keyup fires, value is "".
If you do release the key :
__ keypress fires directly, value is "".

The solution For IE10+ is to use the input event which will fire when the textEditable element's content has changed or, as suggested by @Mayhem, the change event, which won't even listen for key inputs and has a better browser support than input

$('#tbox').on('input change',function(e){
    if($('#tbox').val() !== '') {
        $('#btn').css({'display':'block'});
    } else {
        $('#btn').css({'display':'none'});
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="tbox"></text>
<button type="button" id="btn"  style="display:none;">push me</button>
like image 78
Kaiido Avatar answered Oct 20 '22 01:10

Kaiido


As i've aleady made comments on this one, did a quick google and came across this post which might make it a little easier.. Detect all changes to a <input type="text"> (immediately) using JQuery

So i put it into a fiddle here for you to test: Slight Modded Version

The HTML

<input type="text" value="Some Value" id="text1" />
<button id="btn1">Click Me</button>

The JS

 $('#text1').each(function() {
   var elem = $(this);
   elem.data('oldVal', elem.val());
   elem.bind("propertychange change click keyup input paste", function(event){
      if (elem.data('oldVal') != elem.val()) {
          if (elem.val().length == 0 ) {
              $("#btn1").hide();
          } else {
              $("#btn1").show();
          }
       elem.data('oldVal', elem.val());
     }
   });
 });

As i dont have to much time to break this code down into sections... By the looks of it.. You dont need the elem.data... Just the bind event... ... ah seems i decided to shorten the code for you...

http://jsfiddle.net/z2ew3fqz/3/ Using the same HTML...

Shortest version i could make from the example given above

The HTML

<input type="text" value="Some Value" id="text1" />
<button id="btn1">Click Me</button>

The JS

 $('#text1').bind("propertychange change click keyup input paste", function(event){
     if ($(this).val().length == 0 ) {
         $("#btn1").hide();
     } else {
         $("#btn1").show();
     }
 });

I've quickly tested this on chrome.. mouse/function keys all seem to affect it correctly... Other browsers i'll leave upto the OP to test.. Let me know if any issues in a particular browser..

IE10 seems to be the min support for this .. IE9 might be able to have a js prototype done.. But how important is this for support in your project? to support IE<10?

like image 26
Angry 84 Avatar answered Oct 20 '22 00:10

Angry 84