【问题标题】:Limit jQuery .keydown() to Only specific Keys将 jQuery .keydown() 限制为仅特定键
【发布时间】:2021-11-03 01:47:12
【问题描述】:

我正在使用 WordPress jQuery 为我的网站构建一些快捷方式。

它按预期工作,但是当按下其他键时它不会停止。

例如,如果我按下 f,它会执行必要的任务。但如果我按CTRL + f,它也能完成任务。

事实上,我试过了,其他键,如 fp,也很有效。

我希望它只适用于特定的键。 Incase 任何其他按键,它不应该运行。它应该在单击 f 时运行,但不能在 CTRL + f 上运行。

我在 Windows 7 和 8 上的 Chrome 92.0.4515.159 和 Chrome Beta 版本 94.0.4606.31 上对此进行了测试。

    jQuery(window).keydown(function(e) {
        if( e.which === 27){
            jQuery('.SearchCreationsClose').click();
        }
        if(e.key == "f"){
            e.preventDefault();
            jQuery('.SearchCreationsIcon').click();
        }
    });

【问题讨论】:

    标签: javascript jquery wordpress keyboard keydown


    【解决方案1】:

    如果按下 ctrl 键,则使用 e.ctrlKey:

     jQuery(window).keydown(function(e) {
      if(e.key=='f' && e.ctrlKey){ 
        console.log('ctrl+f');} 
      else if (e.key=='f'){ 
         console.log('"JUST" f key');
      }
     });
    

    如果你只想捕捉 f keydown 而不是 ctrl+f:

     jQuery(window).keydown(function(e) {
       if(e.key=='f' && !e.ctrlKey){ 
         console.log('"JUST" f key');
       }
     });
    

    【讨论】:

    • 好吧,正如我所说,keydown 对每个键都有效,就像我按下 fp 一样,它也会执行相同的任务。我希望它只适用于 f。您的代码阻止了 ctrl+f 但它不会阻止其他组合键
    • 我上面的代码只有当你按下“f”键或ctrl+f的组合时才会记录,其他键或组合不会被记录。不是你想抓的吗?
    • 不。请参阅我的代码if(e.key == "f"){jQuery('.SearchCreationsIcon').click(); 这与您的代码或多或少相同。它在我按 F 时有效,但在我按 x + f 或 y + f 或 shift + f 时它也有效。我希望它只有在我按 F 并且没有按其他键时才能工作
    • 键盘处理程序只能在单个键或与 ctrl、opt、shift 的组合上触发......你应该自己实现如何使用超时捕获其他组合......
    【解决方案2】:

    我认为最好的解决方案是将这个:Can jQuery .keypress() detect more than one key at the same time? 与这样的某种超时合并:

    var keys = {};
    var eventTimeout;
    
    $(document).keydown(function (e) {
      // Reset timeout
      if (eventTimeout) {
        clearTimeout(eventTimeout);
      }
      keys[e.which] = true;
      eventTimeout  = setTimeout(function () {
        if (typeof keys[70] !== "undefined"  && Object.keys(keys).length === 1) { // 70 is the "f" key and it is the only pressed key
          e.preventDefault();
          $('.SearchCreationsIcon').click();
        }
      }, 200); // Takes 200ms of time before going on
    });
    
    $(document).keyup(function (e) {
    setTimeout(function(){
      delete keys[e.which];
    },210);
    });
    

    这个想法是,当您检测到 keydown 时,您会稍等片刻,看看是否有其他键按下或只是“f”键。 keyup 清除缓冲区以确保没有剩菜

    编辑组合: 这将是捕获 CTRL + SHIFT + S 的解决方案,请参阅更新的代码。我只是从 if 中移出代码并嵌套到单独的函数中。您可以轻松地抽象函数以接受同时按下的任意数量的键以及应该按下的键并创建单个函数。你明白了

    var keys = {};
    var eventTimeout;
    
    $(document).keydown(function (e) {
        // Reset timeout
        if (eventTimeout) {
            clearTimeout(eventTimeout);
        }
        keys[e.which] = true;
        eventTimeout  = setTimeout(function () {
            if (isFPressed() || isMyComboPressed()) { // 70 is the "f" key and it is the only pressed key
                e.preventDefault();
                $('.SearchCreationsIcon').click();
            }
        }, 200); // Takes 200ms of time before going on
    });
    
    function isFPressed() {
        return typeof keys[70] !== "undefined" && Object.keys(keys).length === 1;
    }
    
    /**
     * 16 - Key code of SHIFT
     * 17 - Key code of CTRL
     * 83 - Key code of "s"
     * @returns {boolean}
     */
    function isMyComboPressed(){
        return typeof keys[16] !== "undefined" && keys[17] !== "undefined" && keys[83] !== "undefined" && Object.keys(keys).length === 3;
    }
    
    $(document).keyup(function (e) {
        setTimeout(function () {
            delete keys[e.which];
        }, 210);
    });
    

    【讨论】:

    • 在某处读到最好使用 keydown 而不是 keypress... 所以尝试使用 keydown... 无论如何,请允许我一个小时,因为我不在办公室。谢谢你的帮助。
    • 嘿,感谢您的帮助...大部分都有效...实际上,有问题的代码是我网站上的几个快捷键之一...我正在构建另一个涉及 CTRL 和 SHIFT 的快捷方式S 键...这是我使用的代码 if((e.ctrlKey || e.metaKey) && e.shiftKey && e.which == 83){ 如何使用您的代码检查其他两个键?我试过 typeof keys[CTRL] 没用
    • 谢谢,但我已经知道 CTRL 和 SHIFT 的键码。问题是有人告诉我这仅适用于 Windows,要在 macOS 上运行,我需要使用 e.metaKey,那么如何做到这一点...(您可以查看我之前的评论,我如何编码以使用 ctrlKey 或 metaKey)
    • 嘿,我在一个带有长文本区域的页面上使用这些快捷方式,人们经常在其中输入 1000 多个单词......所以超时会不会对 ux 造成困扰,因为我相信超时会占用更多资源我所知?如果是,那么他们可能是更好的方法
    • 我实际上是使用 macOS 编写的代码,因此键必须是正确的。关于我不太了解的性能问题,你应该用密集的写作来测试它,看看它是否会爆炸。在此期间,我会尝试考虑是否有更好的解决方案来解决这个问题
    【解决方案3】:

    我从@diego 看到了答案,并了解您想要实现快捷键,使其仅限于特定的组合键,额外的按键将停止该功能。

    解决方案非常好,但是读取 cmets 有两个主要问题,1.) 当 window 失焦时它会停止,2.) event.preventDefault 不起作用

    我有一个解决方案,它可以在没有超时功能的情况下工作,从而解决e.preventDefault 问题。我使用不同的方法来实现它。

        var MyKeys= 0;
    
        jQuery(window).focus(function(){
            MyKeys = 0;
        });
    
        jQuery(window).keyup(function(e){
            if(MyKeys > 0){
                MyKeys--
            }
            else {
                MyKeys = 0;
            }
        });
    
        jQuery(window).keydown(function(e){
            if (!e.repeat) {
                MyKeys++
            }
            if(e.which == 70 && MyKeys === 1){
                e.preventDefault();
                console.log('f is pressed')
            }
            if(e.which == 70 && (e.ctrlKey || e.metaKey) && MyKeys === 2){
                e.preventDefault();
                console.log('ctrl+f is pressed')
            }
        });
    
    

    很确定它解决了防止默认问题..

    而且我认为它也将解决Alt + Tab 问题...(尚未测试但有信心)

    它并不完美。只有一个小限制,如果用户在已经按下某个键的情况下进入您的 Windows,则他必须先抬起该键,然后才能使用该快捷方式。他不能只按CTRL然后按f。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      • 2013-04-27
      • 1970-01-01
      • 2018-08-01
      相关资源
      最近更新 更多