90

I want to handle F1-F12 keys using JavaScript and jQuery.

I am not sure what pitfalls there are to avoid, and I am not currently able to test implementations in any other browsers than Internet Explorer 8, Google Chrome and Mozilla FireFox 3.

Any suggestions to a full cross-browser solution? Something like a well-tested jQuery library or maybe just vanilla jQuery/JavaScript?

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
cllpse
  • 21,396
  • 37
  • 131
  • 170

15 Answers15

54

I agree with William that in general it is a bad idea to hijack the function keys. That said, I found the shortcut library that adds this functionality, as well as other keyboard shortcuts and combination, in a very slick way.

Single keystroke:

shortcut.add("F1", function() {
    alert("F1 pressed");
});

Combination of keystrokes:

shortcut.add("Ctrl+Shift+A", function() {
    alert("Ctrl Shift A pressed");
});
matsev
  • 32,104
  • 16
  • 121
  • 156
29

The best source I have for this kind of question is this page: http://www.quirksmode.org/js/keys.html

What they say is that the key codes are odd on Safari, and consistent everywhere else (except that there's no keypress event on IE, but I believe keydown works).

mcherm
  • 23,999
  • 10
  • 44
  • 50
  • 2
    I forget where I found it, but Jan Wolter wrote a great page on JavaScript keyboard events too: http://unixpapa.com/js/key.html – Paul D. Waite Jul 05 '17 at 08:04
27

I am not sure if intercepting function keys is possible, but I would avoid using function keys all together. Function keys are used by browsers to perform a variety of tasks, some of them quite common. For example, in Firefox on Linux, at least six or seven of the function keys are reserved for use by the browser:

  • F1 (Help),
  • F3 (Search),
  • F5 (Refresh),
  • F6 (focus address bar),
  • F7 (caret browsing mode),
  • F11 (full screen mode), and
  • F12 (used by several add-ons, including Firebug)

The worst part is that different browsers on different operating systems use different keys for different things. That's a lot of differences to account for. You should stick to safer, less commonly used key combinations.

William Brendel
  • 31,712
  • 14
  • 72
  • 77
  • 7
    Yes, I know that some keys are reserved. Never the less; I want to use whatever keys are not. – cllpse Jan 08 '09 at 14:37
  • 1
    On my computer, all the F-keys are reserved. Using Opera with some custom shortcut. Never EVER relies on "commonly unreserved keys" conventions. – gizmo Jan 08 '09 at 14:39
  • Is there a specific reason? I'm just finding it hard to think of a situation that would require the use of function keys. This is purely curiosity on my part; I'm not trying to talk you out of anything, merely suggesting alternatives. – William Brendel Jan 08 '09 at 14:40
  • 5
    “I want to use whatever keys are not” — Thing is, you can’t tell programmatically what keys aren’t reserved. Taking over the function keys might well be fine for your app, but it’s difficult to tell. – Paul D. Waite Feb 17 '10 at 07:03
  • 3
    @WilliamBrendel I'm working with a handheld industrial scanner. I have to use function keys. – Bmo Nov 18 '14 at 18:01
  • 1
    @Bmo I knew right away it was industrial something; I bet you're trying to mimic ERP functionality in a webpage and need to handle F keys. I'm in that same spot! :) – KingOfAllTrades Oct 02 '18 at 16:36
  • 1
    @WilliamBrendel: After all these years I still wonder if anyone intentionally presses F1... :) – Herbert Van-Vliet Nov 19 '19 at 18:53
  • F1 was traditionally important in 90s on PCs because how to operate a game or program was not always apparent in fullscreen. Web apps now act like programs so someone may want to press F1 to see view how to operate it. – bryc May 23 '20 at 09:48
26

It is very simple.

$(function(){
    //Yes! use keydown because some keys are fired only in this trigger,
    //such arrows keys
    $("body").keydown(function(e){
         //well so you need keep on mind that your browser use some keys 
         //to call some function, so we'll prevent this
         e.preventDefault();

         //now we caught the key code.
         var keyCode = e.keyCode || e.which;

         //your keyCode contains the key code, F1 to F12 
         //is among 112 and 123. Just it.
         console.log(keyCode);       
    });
});
Aloiso Gomes
  • 640
  • 6
  • 12
  • 2
    I like your approach the best since it allows you to capture the keys you want and pass on the rest. I noticed with your solution i problem. things like ctrl + shift + r was also captured. if you want every event to be canceled this is great. but i would suggest to do it in your logic itself. if(key == x) {e.preventDefault(); (your logic goes here)} return e to help resolve that problem. – Cees Jun 29 '21 at 02:11
13

Without other external class you can create your personal hack code simply using

event.keyCode

Another help for all, I think is this test page for intercept the keyCode (simply copy and past in new file.html for testing your event).

 <html>
 <head>
 <title>Untitled</title>
 <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
 <style type="text/css">
 td,th{border:2px solid #aaa;}
 </style>
 <script type="text/javascript">
 var t_cel,tc_ln;
 if(document.addEventListener){ //code for Moz
   document.addEventListener("keydown",keyCapt,false); 
   document.addEventListener("keyup",keyCapt,false);
   document.addEventListener("keypress",keyCapt,false);
 }else{
   document.attachEvent("onkeydown",keyCapt); //code for IE
   document.attachEvent("onkeyup",keyCapt); 
   document.attachEvent("onkeypress",keyCapt); 
 }
 function keyCapt(e){
   if(typeof window.event!="undefined"){
    e=window.event;//code for IE
   }
   if(e.type=="keydown"){
    t_cel[0].innerHTML=e.keyCode;
    t_cel[3].innerHTML=e.charCode;
   }else if(e.type=="keyup"){
    t_cel[1].innerHTML=e.keyCode;
    t_cel[4].innerHTML=e.charCode;
   }else if(e.type=="keypress"){
    t_cel[2].innerHTML=e.keyCode;
    t_cel[5].innerHTML=e.charCode;
   }
 }
 window.onload=function(){
   t_cel=document.getElementById("tblOne").getElementsByTagName("td");
   tc_ln=t_cel.length;
 }
 </script>
 </head>
 <body>
 <table id="tblOne">
 <tr>
 <th style="border:none;"></th><th>onkeydown</th><th>onkeyup</th><th>onkeypress</td>
 </tr>
 <tr>
 <th>keyCode</th><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
 </tr>
 <tr>
 <th>charCode</th><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
 </tr>
 </table>
 <button onclick="for(i=0;i<tc_ln;i++){t_cel[i].innerHTML='&nbsp;'};">CLEAR</button>
 </body>
 </html>

Here is a working demo so you can try it right here:

var t_cel, tc_ln;
if (document.addEventListener) { //code for Moz
  document.addEventListener("keydown", keyCapt, false);
  document.addEventListener("keyup", keyCapt, false);
  document.addEventListener("keypress", keyCapt, false);
} else {
  document.attachEvent("onkeydown", keyCapt); //code for IE
  document.attachEvent("onkeyup", keyCapt);
  document.attachEvent("onkeypress", keyCapt);
}

function keyCapt(e) {
  if (typeof window.event != "undefined") {
    e = window.event; //code for IE
  }
  if (e.type == "keydown") {
    t_cel[0].innerHTML = e.keyCode;
    t_cel[3].innerHTML = e.charCode;
  } else if (e.type == "keyup") {
    t_cel[1].innerHTML = e.keyCode;
    t_cel[4].innerHTML = e.charCode;
  } else if (e.type == "keypress") {
    t_cel[2].innerHTML = e.keyCode;
    t_cel[5].innerHTML = e.charCode;
  }
}
window.onload = function() {
  t_cel = document.getElementById("tblOne").getElementsByTagName("td");
  tc_ln = t_cel.length;
}
td,
th {
  border: 2px solid #aaa;
}
<html>

<head>
  <title>Untitled</title>
  <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
</head>

<body>
  <table id="tblOne">
    <tr>
      <th style="border:none;"></th>
      <th>onkeydown</th>
      <th>onkeyup</th>
      <th>onkeypress</td>
    </tr>
    <tr>
      <th>keyCode</th>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <th>charCode</th>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
  </table>
  <button onclick="for(i=0;i<tc_ln;i++){t_cel[i].innerHTML='&nbsp;'};">CLEAR</button>
</body>

</html>
Chris Baker
  • 49,926
  • 12
  • 96
  • 115
paladinux
  • 131
  • 1
  • 2
  • 1
    Thanks @paladinux, your code is working fine for me. I am customizing it to call custom functions on key press. But I am facing one issue. Whenever I type characters 'q,r,s,t,u', page automatically executes the custom functions as these keys have same keycodes as function keys F2...F7 (113..118) – raj Aug 02 '14 at 13:11
7

Solution in ES6 for modern browsers and IE11 (with transpilation to ES5):

//Disable default IE help popup
window.onhelp = function() {
    return false;
};
window.onkeydown = evt => {
    switch (evt.keyCode) {
        //ESC
        case 27:
            this.onEsc();
            break;
        //F1
        case 112:
            this.onF1();
            break;
        //Fallback to default browser behaviour
        default:
            return true;
    }
    //Returning false overrides default browser event
    return false;
};
keemor
  • 1,149
  • 15
  • 16
2

This works for me.

if(code ==112) { alert("F1 was pressed!!"); return false; }

F2 - 113, F3 - 114, F4 - 115, and so fort.

Christine
  • 21
  • 1
2

You can use Vanilla Javascript and the KeyboardEvents keydown, keypress or keyup.

Use event.key (preferably) or event.code and compare them against the key name like event.key === "F1".

When working with Function keys you probably want to suppress the default behaviour (On windows many of the function keys are used by the browser). This can be achieved by calling preventDefault() on the keydown event. Even if you want to listen to the keyup event you need to call preventDefault() on the keydown event, because the browser shortcut is bound to that event. Keep in mind, that calling preventDefault() on keydown will also suppress the keypress event.

document
  .addEventListener("keydown", e => {
    if(e.key === "F1") {
      // Suppress default behaviour 
      // e.g. F1 in Microsoft Edge on Windows usually opens Windows help
      e.preventDefault()
    }
  })

document
  .addEventListener("keyup", e => {
    if(e.key === "F1") {
      // Handle the keyup event
      doSomething()
    }
  })
JoCa
  • 1,045
  • 9
  • 14
1

One of the problems in trapping the F1-F12 keys is that the default function must also be overridden. Here is an example of an implementation of the F1 'Help' key, with the override that prevents the default help pop-up. This solution can be extended for the F2-F12 keys. Also, this example purposely does not capture combination keys, but this can be altered as well.

<html>
<head>
<!-- Note:  reference your JQuery library here -->
<script type="text/javascript" src="jquery-1.6.2.min.js"></script>
</head>
<body>
    <h1>F-key trap example</h1>
    <div><h2>Example:  Press the 'F1' key to open help</h2></div>
    <script type="text/javascript">
        //uncomment to prevent on startup
        //removeDefaultFunction();          
        /** Prevents the default function such as the help pop-up **/
        function removeDefaultFunction()
        {
            window.onhelp = function () { return false; }
        }
        /** use keydown event and trap only the F-key, 
            but not combinations with SHIFT/CTRL/ALT **/
        $(window).bind('keydown', function(e) {
            //This is the F1 key code, but NOT with SHIFT/CTRL/ALT
            var keyCode = e.keyCode || e.which;
            if((keyCode == 112 || e.key == 'F1') && 
                    !(event.altKey ||event.ctrlKey || event.shiftKey || event.metaKey))
             {
                // prevent code starts here:
                removeDefaultFunction();
                e.cancelable = true;
                e.stopPropagation();
                e.preventDefault();
                e.returnValue = false;
                // Open help window here instead of alert
                alert('F1 Help key opened, ' + keyCode);
                }
            // Add other F-keys here:
            else if((keyCode == 113 || e.key == 'F2') && 
                    !(event.altKey ||event.ctrlKey || event.shiftKey || event.metaKey))
             {
                // prevent code starts here:
                removeDefaultFunction();
                e.cancelable = true;
                e.stopPropagation();
                e.preventDefault();
                e.returnValue = false;
                // Do something else for F2
                alert('F2 key opened, ' + keyCode);
                }
        });
    </script>
</body>
</html>

I borrowed a similar solution from a related SO article in developing this. Let me know if this worked for you as well.

Community
  • 1
  • 1
MAbraham1
  • 1,717
  • 4
  • 28
  • 45
1

Just add this event listener:

function keyDown(e)
{
    let charStr, key = e.which || e.keyCode;
    if (key >= 112 && key <= 123)
    {
        e.preventDefault();
        e.stopPropagation();
        charStr = "F" + (key - 111);
        switch (charStr)
        {
            case "F1":
                alert("F1");
                break;
            case "F2":
                alert("F2");
                break;
            default:
                alert("Other F key");
                break;
        }
    }
}

document.addEventListener('keydown', keyDown);

This has very good browser compatibility. I don't know about Internet Explorer 8 or Mozilla FireFox 3, but hardly still relevant in 2022.

Dan Bray
  • 7,242
  • 3
  • 52
  • 70
0

My solution to this problem is:

document.onkeypress = function (event) {
    event = (event || window.event);
    if (event.keyCode == 123) { 
         return false;
    }
}

With the magic number 123 which is the key F12.

Didier Aupest
  • 3,227
  • 2
  • 23
  • 35
0

Consider that your app will not be remotely mobile friendly.

Gregory
  • 73
  • 1
  • 6
-1

Add a shortcut:

$.Shortcuts.add({
    type: 'down',
    mask: 'Ctrl+A',
    handler: function() {
        debug('Ctrl+A');
    }
});

Start reacting to shortcuts:

$.Shortcuts.start();

Add a shortcut to “another” list:

$.Shortcuts.add({
    type: 'hold',
    mask: 'Shift+Up',
    handler: function() {
        debug('Shift+Up');
    },
    list: 'another'
});

Activate “another” list:

$.Shortcuts.start('another');
Remove a shortcut:
$.Shortcuts.remove({
    type: 'hold',
    mask: 'Shift+Up',
    list: 'another'
});

Stop (unbind event handlers):

$.Shortcuts.stop();


Tutorial:
http://www.stepanreznikov.com/js-shortcuts/

KingRider
  • 2,140
  • 25
  • 23
-1

Try this solution if works.

window.onkeypress = function(e) {
    if ((e.which || e.keyCode) == 116) {
        alert("fresh");
    }
}
default locale
  • 13,035
  • 13
  • 56
  • 62
-1

You can do this with jquery like this:

        $("#elemenId").keydown(function (e) {
            if(e.key == "F12"){
                console.log(e.key);
            }

        });
Javier Menéndez Rizo
  • 2,138
  • 3
  • 12
  • 22