如何避免jQuery的keydown延迟?

时间:2015-08-06 03:59:23

标签: javascript jquery delayed-execution

目标:

当用户在文本框中键入字符时,会出现一个按钮。当用户使用退格键清除文本框但按住该键几秒钟时,立即隐藏该按钮。

ISSUE:

如果用户键入单个字符,并使用退格键将其删除 - 通过按住退格键几秒钟 - 隐藏按钮之前会有一段延迟。仅当用户只键入一个字符然后按住退格键而不放手时才会发生这种情况。如果用户输入多个字符,然后按住退格键直到文本框为空,则隐藏按钮没有延迟。

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

4 个答案:

答案 0 :(得分:4)

稍微了解一下情况:

假设<input>值为"x"且您键入退格键:
- 当keydown事件触发时,输入的值仍为"x" - 当keypress触发时,它仍为"x" 如果您没有释放密钥:
__ keydown再次触发,经过一段时间的延迟,取决于os我猜值现在是""
__ keypress再次触发,值仍为"" __当您释放密钥时,keyup会触发,值为"" 如果您执行释放密钥:
__ keypress直接触发,值为""

对于IE10 +的解决方案是使用input事件,该事件将在textEditable元素的内容发生变化时触发,或者如@Mayhem所建议的那样,change事件赢得&# 39;甚至可以监听关键输入,并且比input

具有更好的浏览器支持

&#13;
&#13;
$('#tbox').on('input change',function(e){
    if($('#tbox').val() !== '') {
        $('#btn').css({'display':'block'});
    } else {
        $('#btn').css({'display':'none'});
    }
});
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

由于我已经对这个发表了评论,快速谷歌并发现了这篇文章,这可能会让它变得更容易...... Detect all changes to a <input type="text"> (immediately) using JQuery

所以我把它放在一个小提琴里供你测试:Slight Modded Version

HTML

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

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());
     }
   });
 });

因为我没有太多时间将这些代码分解成各个部分...通过它的外观..你不需要elem.data ...只是绑定事件... ......啊似乎我决定为你缩短代码...

http://jsfiddle.net/z2ew3fqz/3/ 使用相同的HTML ...

我可以根据上面给出的示例制作最短版本

HTML

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

JS

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

我已经在chrome上快速测试了这个..鼠标/功能键似乎都正确地影响了它...其他浏览器我将留给OP进行测试..如果特定浏览器中有任何问题,请告诉我。

IE10 似乎是对此的最低支持.IE9可能能够完成js原型..但是这对于你的项目中的支持​​有多重要?支持IE&lt; 10?

答案 2 :(得分:1)

问题是$('#tbox')。val();按下退格键时不为空('')。所以你必须推迟价值检查。

当你按下键时,首先发生的是keydown事件被触发,然后在输入字段上执行键操作。

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

});

答案 3 :(得分:0)

您可以通过全局变量控制键来防止重复键控:

var allow = true;
$(document).on('keydown', function(e) { 
  if (e.repeat != undefined) {
    allow = !e.repeat;
  }
  if (!allowed) return;
  allowed = false;

  if($('#tbox').val() !== '') {
        $('#btn').css({'display':'block'});
    } else {
        $('#btn').css({'display':'none'});
    }
});

$(document).keyup(function(e) { 
  allowed = true;
});