skip to Main Content

I am using WordPress jQuery to build some shortcuts for my site.

It works as intended, however it doesn’t stop when other keys are pressed.

For example, if I press, f it performs the necessary task. But if I press CTRL + f then also it does the task.

Infact, I tried, other keys like f and p and that too worked.

I want it to only work on the specific key. Incase of any other key press, it should not run. It should run on clicking f, but NOT run on CTRL + f.

I tested this on Chrome 92.0.4515.159 and Chrome Beta Version 94.0.4606.31 on Windows 7 and 8.

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

3

Answers


  1. Use e.ctrlKey which is true if ctrl key was pressed:

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

    If you want to catch only f keydown but not ctrl+f:

     jQuery(window).keydown(function(e) {
       if(e.key=='f' && !e.ctrlKey){ 
         console.log('"JUST" f key');
       }
     });
    
    Login or Signup to reply.
  2. I think the best solution would be to merge this: Can jQuery .keypress() detect more than one key at the same time? with some sort of timeout like this:

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

    The idea is that when you detect keydown you wait a little bit to see if there are others key pressed or just the "f" key. The keyup clears the buffer to ensure there are no leftovers

    Edit for combo:
    This would be the solution to catch CTRL + SHIFT + S, see updated code. I just moved out code from if and nested into separated function. You could easily abstract the function to accept an arbitrary number of keys simultaneously pressed together with which keys should be pressed and create a single function. You got the idea

    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);
    });
    
    Login or Signup to reply.
  3. I saw the answer from @diego and understand that you want to implement shortcuts such that they are limited to a specific key combination, extra keypress will stop the function.

    The solution was really good, but reading comments there are 2 main problems, 1.) It stops when the window goes out of focus, and 2.) event.preventDefault doesn’t not work

    I have a solution, that works without the timeout function, making it solve the e.preventDefault problem. And I use a different approach to make it happen.

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

    Pretty sure that it solves the prevent default problem..

    And I think it will solve the Alt + Tab problem too… (Haven’t tested but am confident)

    It isn’t perfect. There is only a small limitation, if a user comes focuses into your Windows with a key already pressed, he would have to lift the key before being able to use the shortcut. He cants just focus in with CTRL pressed and then press f.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search