使用JQuery检测空格键按下的最快方法是什么?

4
我们有一个Web应用程序,允许用户扫描条形码或单击链接,隐藏条形码输入并显示JQuery Chosen选择菜单。
为了节省用户手动在产品搜索选择菜单和条形码输入之间切换的时间,我正在检查条形码输入字段中的空格键按下情况,然后切换输入并预填用户搜索词的Chosen选择菜单。它可以正确地工作,但由于检查空格键按下而导致条形码输入变得缓慢。
我是Javascript的新手,这是我的第一次尝试。是否有人能够向我展示更快或更有效的方法来检查空格键按下?这是我们员工的内部Web应用程序,并且仅需要在运行在MacOS上的Safari或Chrome中工作。非常感谢任何帮助。
$("input#barcodeIn").keyup(function(e){
// CHECK FOR SPACEBAR PRESS IN THE BARCODE INPUT FIELD
if (e.keyCode == 32) {
    // SHOW CHOSEN MENU INSTEAD OF BARCODE INPUT BECAUSE WE'RE TYPING A PRODUCT NAME
    $("#inputSwitch").trigger("click");

    // AUTOMATICALLY OPEN THE CHOSEN MENU
    $("#cbProduct").trigger("chosen:open");

    // GRAB WHAT WAS ENTERED INTO THE BARCODE INPUT
    var input = $("#barcodeIn").val()+" ";

    // ENTER THE INPUT TEXT INTO THE CHOSEN SELECT MENU
    $(".chosen-search input").val(input);

    // CLEAR THE BARCODE INPUT BECAUSE WE"RE USING THE CHOSEN SELECT MENU INSTEAD
    $("#barcodeIn").val("");
    return false;
}});

到底是什么在占用时间?我不明白事件钩子会慢在哪里。 - Rory McCrossan
当您在输入#barcodeIn中输入文本时,字符出现在输入框中会有短暂的延迟。当您快速扫描条形码时,这尤其明显。 - Matt
那样更有意义。谢谢你。 - Rory McCrossan
基于您的建议,事件钩子不应该很慢,我创建了一个快速的jsFiddle作为测试,结果证明您是完全正确的。我移除了Chosen Select库,现在没有延迟了。这似乎是我的函数和页面中有Chosen Select菜单的组合问题。我会更新我的问题。 - Matt
2个回答

3
您的不响应行为可能有以下几个潜在原因:
  1. 您正在等待 keyup 事件,因此无论他们多么快地按下空格键,只有在释放时您的代码才会响应。
  2. 在事件中,您正在执行一些缓慢的操作,这也可能会引起(微小的)延迟
    1. 通过选择器查找元素很慢,请尽可能缓存结果
      • 在我的示例中,我避免了缓存 $('.chosen-search input'),因为我不确定它是否会动态更改。
      • 无论如何,为了加快速度,您仍然可以缓存:var $chosenSearch = $('.chosen-search'),然后稍后使用:$('input',$chosenSearch) 进行选择
    2. 除非有意延迟本机行为(和其他处理程序),否则在事件处理程序中执行的任何代码都应尽快返回
      • 在这种情况下,这完全是过度设计,但我已经展示了如何使用 setTimeout() 异步执行您的代码,以便事件处理程序返回,然后执行您的代码。
      • 虽然可能不明显为什么要这样做,但想象一下,如果您的代码需要(例如)1.5 秒才能执行 - 在这种情况下,每次用户键入的按键都会在输入框中显示之前有 1.5 秒的延迟
      • 通过将其放入 setTimeout() 中,您可以确保无论处理时间多长,按键都至少会先响应。

希望这能帮到您!


$(function() {

  // cache the selectors to avoid re-scanning inside the event handler
  var $inputSwitch = $('#inputSwitch');
  var $cbProduct = $('#cbProduct');
  var $barcodeIn = $('#barcodeIn');

  // Not strictly necessary, but saves the messiness of callback-in-callback
  function swapContext() {
      // SHOW CHOSEN MENU INSTEAD OF BARCODE INPUT BECAUSE WE'RE TYPING A PRODUCT NAME
      $inputSwitch.trigger("click");

      // AUTOMATICALLY OPEN THE CHOSEN MENU
      $cbProduct.trigger("chosen:open");

      // GRAB WHAT WAS ENTERED INTO THE BARCODE INPUT
      var input = $("#barcodeIn").val()+" ";

      // ENTER THE INPUT TEXT INTO THE CHOSEN SELECT MENU
      $(".chosen-search input").val(input);

      // CLEAR THE BARCODE INPUT BECAUSE WE"RE USING THE CHOSEN SELECT MENU INSTEAD
      $barcodeIn.val("");    
  }

  $("input#barcodeIn").on('keydown', function(e){
  // CHECK FOR SPACEBAR PRESS IN THE BARCODE INPUT FIELD

  if (e.keyCode == 32) {
      // Ensures we can return from the handler quickly
      setTimeout( swapContext, 0 );
      return false;
  }});  

});

由于您也是Javascript的新手,请注意下面的var声明是包装函数本地的,JS中绝对要避免使用全局变量,最好学习避免它们的略微奇怪的方式(并在此过程中,学习许多有趣的javascript技巧)。

1
非常感谢您详细的解释和额外的提示。我尝试了您的版本,但行为没有改变。然而,我发现如果我用普通的选择菜单替换隐藏的选择菜单,延迟就会消失。似乎存在一个错误,我现在需要花些时间来缩小范围。我接受这个答案,因为它肯定是我第一次尝试该函数的更有效的版本。谢谢。 - Matt
1
@Matt 啊,很抱歉那没能解决你的问题(不过至少我很高兴它缩小了错误搜索范围!)。当你找出原因时,请分享一下经验。 - pentaphobe
在我的Debian系统上,e.keyCode返回的是229而不是32。 - towry

1

请在链接中放置一个简短的摘要,以便如果链接在未来出现404错误,访问者仍然能够从您的答案中了解该链接原本提供的摘要。 - krishwader
嗯,链接有点奇怪,但对我来说很正常,我加了“www”可能现在可以用了。我还添加了一个代码片段来说明我的答案。 - sidarcy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接