如何避免 jQuery 的按键延迟?

How to avoid keydown delay with jQuery?

目标:

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

问题:

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

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

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

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

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

当您按下按键时,首先会触发 keydown 事件,然后会在输入字段上执行按键操作。

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

});

情况的一些演练:

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

IE10+的解决方案是使用input event which will fire when the textEditable element's content has changed or, as suggested by @Mayhem, the change事件,它甚至不会监听按键输入,并且比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>

因为我已经对此发表了评论,所以快速 google 发现了这个 post 这可能会让它变得更容易一些.. Detect all changes to a <input type="text"> (immediately) using JQuery

所以我把它放到fiddle这里给大家测试一下: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 上快速测试了这个。mouse/function 键似乎都能正确影响它...其他浏览器我会留给 OP 来测试..让我知道如果特定浏览器有任何问题..

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