14

I cannot find a way to detect arrow keys in a text field in Safari and Chrome on an iPad when a bluetooth keyboard is used.
Using this test HTML and JavaScript, touch the input field to give it focus.
Using the arrow keys nothing happens, but type letters and numbers and the keydown events occur.

<!DOCTYPE html>
<html>
<head>
  <title>Test page.</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
  <form>
    <input id="input" style="width: 600px;" type="textarea" />
  </form>
  <div id="keydisp" style="width 600px; height: 50px"></div>
  <script type="text/javascript">
    $(document).keydown(function(event) {
      var keyCode = event.which;
      document.getElementById("keydisp").innerHTML = "key pressed: " + keyCode;
    });
  </script>
</body>
</html>

Is it possible to detect the arrows?

Sean N.
  • 963
  • 2
  • 10
  • 23
  • 1
    try checking `window.event`, not just the `event` that gets passed. ex: `var keyCode = event.which || window.event;` – basher May 13 '15 at 17:05
  • @basher That will not help. According to the jQuery **keydown** documentation `jQuery normalizes the .which property so you can reliably use it to retrieve the key code`. – Sean N. May 14 '15 at 16:32
  • Is the even even firing? Add this to the begining of your function and see if you get the pop up. `alert('keydown event');` I would do this myself but I left my iPad at work. Also; does the event fire for printable characters (A-Z, numbers, etc..)? – Andrew Bonsall May 24 '16 at 00:26
  • @AndrewBonsall I have tried doing keydown and other events. It does fire for other characters. Events for Arrow keys and tabs don't work. – Shiv Deepak May 24 '16 at 01:04
  • 3
    I'm sorry I just found this, which based on what you have told me, nothing has changed [http://stackoverflow.com/questions/14959048/how-to-detect-key-down-event-for-arrow-key-on-textarea](http://stackoverflow.com/questions/14959048/how-to-detect-key-down-event-for-arrow-key-on-textarea) – Andrew Bonsall May 24 '16 at 01:08
  • And the reason for the down-vote on a working example.??? I see someone woke up with a bad mood as it seems... –  May 26 '16 at 05:27
  • @PeterDarmis probably because your code is essentially the same as what I posted. The issue is that the keydown event never gets fired when using a bluetooth keyboard on the ipad. This is probably something that needs fixed in Safari. It would be nice if someone could find a work-around. – Sean N. May 27 '16 at 18:36
  • @SeanN. you mean only Safari does not detect arrow keys with neither one of the answers using a wireless keyboard on ipad? Do the rest of the most popular browsers detect it, using examples from answers on your ipad? –  May 27 '16 at 20:01
  • @SeanN. Now if this is only a problem for you in safari then i would advise the following but please add some feedback to see if this is a good tactic and to add it in answer. use `keypress` for safari. Additionally you could try on `keypress` the following `if (event.which == null) char= String.fromCharCode(event.keyCode); // old IE else if (event.which != 0 && event.charCode != 0) char= String.fromCharCode(event.which); // All others else // special key` check chapter 5. in http://unixpapa.com/js/key.html –  May 28 '16 at 17:28
  • @SeanN. this is a well chosen question my edited answer includes a small snippet which shows you some of the `KeyboardEvent` attributes that in this case are needed. Some are deprecated some are not, some will be according to MDN, you can try a cross-browser check. You will probably solve this with a combination of `event.key` and `event.code` –  May 30 '16 at 18:51

4 Answers4

13

I understand that this might seem like a grim answer and I apologise if it is.

I have struggled with this issue a few weeks ago and eventually gave up on it.
Countless hours of trying to get the arrow keys on the iPad to fire the onkeydown event did seem to work at all, it was like they weren't even being pressed.

A good alternative for a game (or something like that) is to use the WSAD keys, this was what I did.

The codes for the WSAD keys are:

w: 87,
s: 83,
a: 65,
d: 68

This is how you would normally detect when the WSAD keys have been pressed:

$(document).on("keydown", function(event) {
  if (event.which == 87) {
    // W key Has Been Pressed
  } else if (event.which == 83) {
    // S key Has Been Pressed
  } else if (event.which == 65) {
    // A key Has Been Pressed
  } else if (event.which == 68) {
    // D key Has Been Pressed
  }
  // prevent the default action
  // event.preventDefault(); // This is optional.
});

The codes for the arrow keys are:

up: 38,
down: 40,
left: 37,
right: 39

This is how you would normally detect when the arrows keys have been pressed:

$(document).on("keydown", function(event) {
  if (event.which == 37) {
    // Left Arrow Has Been Pressed
  } else if (event.which == 38) {
    // Up Arrow Has Been Pressed
  } else if (event.which == 39) {
    // Right Arrow Has Been Pressed
  } else if (event.which == 40) {
    // Down Arrow Has Been Pressed
  }
  // prevent the default action
  event.preventDefault();
});

NOTE: you can only use the onkeydown event to check if the the arrow keys have been pressed.

You can also use var key = event.keyCode ? event.keyCode : event.which;
Quoting Peter Darmis:

Versions of Opera before 10.50 messes up by returning non-zero event.which values for four special keys (Insert, Delete, Home and End), meaning using event.keyCode may be more "fail safe" across older browsers.
Source

Quoting the jQuery api:

The event.which property normalizes event.keyCode and event.charCode. It is recommended to watch event.which for keyboard key input. For more detail, read about event.charCode on the MDN.
Source

Good luck, and all the best.

Community
  • 1
  • 1
  • 1
    Can you please write in your answer regarding `charCode` which is normailzed by `.which()`... again *quote by Peter Darmis* if you want i don't mind... the [notes][https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/charCode#Notes] of charCode in MDN and specially the part with `keydown` and `charCode`??? If i remember it writes `charCode is never set in the keydown and keyup events. In these cases, keyCode is set instead.` –  May 27 '16 at 19:28
  • 1
    As you understand @Mango i am not here to argue anyone, i just posted my answer. I am also learning from this website... and a lot :) now since which normalizes `keyCode` and `charCode` it means that most probably (i have not seen internal code of which() ever) it uses both in a proper way. So basically you could say that in my answer the `var key = event.keyCode ? event.keyCode : event.which;` part is a redundancy. No it is proper coding. Since `keyCode` is set on `keydown` you could try first of all to see if you get value from that, if it fails then you can move to using `which()` –  May 27 '16 at 19:45
  • 1
    this is a part of latest jQuery... `// Includes some event props shared by KeyEvent and MouseEvent props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), fixHooks: {}, keyHooks: { props: "char charCode key keyCode".split( " " ), filter: function( event, original ) { // Add which for key events if ( event.which == null ) { event.which = original.charCode != null ? original.charCode : original.keyCode; } return event; } },` –  May 27 '16 at 19:47
  • @PeterDarmis Thanks for the update, I'm looking into it. Also if you would like to give me more input you can use http://chat.stackoverflow.com/rooms/113088/discussion-between-mango-and-peter-darmis, I have `desktop notifications` enabled and I can respond to your messages faster. –  May 27 '16 at 20:00
4

For most browsers you could use something like

function returnKeyCode(e) {
  var keyCode = e.keyCode ? e.keyCode : e.which;
  switch (keyCode) {
    case 37:
      alert(e.code ? e.code : e.key);
      break;
    case 38:
      alert(e.code ? e.code : e.key);
      break;
    case 39:
      alert(e.code ? e.code : e.key);
      break;
    case 40:
      alert(e.code ? e.code : e.key);
      break;
    default:
      alert(e.code ? e.code : e.key);
  }
}
window.addEventListener("keydown", function (e) {
  returnKeyCode(e);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

But if you would like to be more thorough take a look at the following snippet. Before that take a look on KeyboardEvent attributes that are used and will be deprecated, or are deprecated.

PS: check the difference in event.code when using jQuery(red) and when javascript(blue).

$(document).on("keydown", function(event) {
  $("#keydown").append("<br><span>keyCode</span>= " + event.keyCode);
  $("#keydown").append("<br><span>key</span>= " + event.key);
  $("#keydown").append("<br><span>code</span>= " + event.code);
  $("#keydown").append("<br><span>which</span>= " + event.which);
  $("#keydown").append("<br><span>charCode</span>= " + event.charCode);
  $("#keydown").append("<br><span>char</span>= " + event.char);
  $("#keydown").append("<br><span>keyIdentifier</span>= " + event.keyIdentifier);
}).on("keypress", function(event) {
  $("#keypress").append("<br><span>keyCode</span> = " + event.keyCode);
  $("#keypress").append("<br><span>key</span> = " + event.key);
  $("#keypress").append("<br><span>code</span> = " + event.code);
  $("#keypress").append("<br><span>which</span> = " + event.which);
  $("#keypress").append("<br><span>charCode</span> = " + event.charCode);
  $("#keypress").append("<br><span>char</span>= " + event.char);
  $("#keypress").append("<br><span>keyIdentifier</span>= " + event.keyIdentifier);
}).on("keyup", function(event) {
  $("#keyup").append("<br><span>keyCode</span> = " + event.keyCode);
  $("#keyup").append("<br><span>key</span> = " + event.key);
  $("#keyup").append("<br><span>code</span> = " + event.code);
  $("#keyup").append("<br><span>which</span> = " + event.which);
  $("#keyup").append("<br><span>charCode</span> = " + event.charCode);
  $("#keyup").append("<br><span>char</span>= " + event.char);
  $("#keyup").append("<br><span>keyIdentifier</span>= " + event.keyIdentifier);
});
window.addEventListener("keydown", function (event) {
  $("#keydown").append("<br><i>keyCode</i>= " + event.keyCode);
  $("#keydown").append("<br><i>key</i>= " + event.key);
  $("#keydown").append("<br><i>code</i>= " + event.code);
  $("#keydown").append("<br><i>which</i>= " + event.which);
  $("#keydown").append("<br><i>charCode</i>= " + event.charCode);
  $("#keydown").append("<br><i>char</i>= " + event.char);
  $("#keydown").append("<br><i>keyIdentifier</i>= " + event.keyIdentifier);
});
window.addEventListener("keypress", function (event) {
  $("#keypress").append("<br><i>keyCode</i>= " + event.keyCode);
  $("#keypress").append("<br><i>key</i>= " + event.key);
  $("#keypress").append("<br><i>code</i>= " + event.code);
  $("#keypress").append("<br><i>which</i>= " + event.which);
  $("#keypress").append("<br><i>charCode</i>= " + event.charCode);
  $("#keypress").append("<br><i>char</i>= " + event.char);
  $("#keypress").append("<br><i>keyIdentifier</i>= " + event.keyIdentifier);
});
window.addEventListener("keyup", function (event) {
  $("#keyup").append("<br><i>keyCode</i>= " + event.keyCode);
  $("#keyup").append("<br><i>key</i>= " + event.key);
  $("#keyup").append("<br><i>code</i>= " + event.code);
  $("#keyup").append("<br><i>which</i>= " + event.which);
  $("#keyup").append("<br><i>charCode</i>= " + event.charCode);
  $("#keyup").append("<br><i>char</i>= " + event.char);
  $("#keyup").append("<br><i>keyIdentifier</i>= " + event.keyIdentifier);
});
$(document).on("click", function() {
$("span, i").remove();
});
span {
  color:#f00;
}
i {
  color:#00f;  
}
.container {
display:inline-flex;
width:100%;
height:auto;
align-items: stretch;
align-content: center;
justify-content: center;
flex-direction: row;
}
.container div{
align-self: stretch;
width: 30%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="keydown">Keydown Event</div>
<div id="keypress">Keypress Event</div>
<div id="keyup">Keyup Event</div>
</div>
  • Please remember that `event.keyCode` is **NOT** supported in *all* browsers, `event.which` is normalized by jQuery, meaning it works across *all* browsers. –  May 26 '16 at 05:44
  • doesn't this little piece of code `var keyCode = e.keyCode ? e.keyCode : e.which;`, satisfy the fact that `event.keyCode` is NOT supported in all browsers??? @Mango Can you please tell me from that line what will be the value of `var keyCode` if `e.keyCode` is undefined? –  May 26 '16 at 06:07
  • Granted the `keyCode` variable will not be undefined but that is not my point, what I'm saying is, what is the point of checking if `event.keyCode` is supported when you know for a fact that `event.which` is always going to be supported? –  May 26 '16 at 06:11
  • Yes you are right at that `event.which` is well supported by almost all `latest` browsers. So why should we check for `event.keyCode`? But those two are not exactly the same in the first way... And check this too - http://unixpapa.com/js/key.html - regarding `event.which`: "Versions of Opera before 10.50 messes up by returning non-zero event.which values for four special keys (Insert, Delete, Home and End). " It is more fail safe across older browsers. That is why i use `event.keyCode` as well. But yet thanks for your down-vote it was well explained. @Mango –  May 26 '16 at 06:31
  • The event.which property normalizes `event.keyCode` and `event.charCode`. It is recommended to watch `event.which` for keyboard key input. `event.which` also normalizes button presses (`mousedown` and `mouseupevents`), reporting 1 for left button, 2 for middle, and 3 for right. Source: https://api.jquery.com/event.which/. Why use something that *might* follow standards over something that **DOES** follow standards? –  May 26 '16 at 06:44
  • I have down voted your answer because of this reason, although I now feel like our discussion has come to a dead end simply because neither of us are wrong. My vote can only be changed by only if you edit your post. Thank you for this learning experience I hope, we can do it again sometime. Good night. –  May 26 '16 at 06:45
  • `event.keyCode` and `event.which` are not identical, if they where one of them would have been deprecated or would stop being used eventually. Since each one has different action on some browsers and/or browser versions, it should be clever enough to understand that `e.which` is an excellent choice for an answer and well spoken. But using both in combination is simply better. Anyway, thanks for the down-vote. In here you can get down-voted for being right. Nice!!! @Mango –  May 26 '16 at 18:44
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/113088/discussion-between-mango-and-peter-darmis). –  May 27 '16 at 00:33
  • I tried your last code snippet in both Chrome and Safari on the iPad with the Bluetooth keyboard. Here is the output of the "up" arrow key: http://imgur.com/yg5UsFE – Sean N. May 31 '16 at 22:56
  • @SeanN. not very good image :( last thing i would like to throw on the table is something like this http://apple.stackexchange.com/questions/112499/configuring-custom-keys-on-bluetooth-keyboard. If there is a way to reconfigure the keys then do it. Best regards –  May 31 '16 at 23:50
1

This might be an additional or something to what the others have given. In this example, key W is being checked if pressed.

$(document).keydown(function(e){
     var event = e.which || e.keyCode;
     if (event == 87){ alert("C was Pressed."); }
});

You can check if keyCode or which is usable, depending on your browser type and version.

For more Keyboard Events Info.

For Event Keycodes.

Community
  • 1
  • 1
rhavendc
  • 985
  • 8
  • 21
0

The problem is probably caused by default behaviour of pressing arrow keys in a iPad. Normally arrow keys scroll the document. But when the text field is focused, the default is prevented. It may be in the implementation of the browser which also stops the bubbling.

Instead of listening to document events, you can also listen to input field's events. See Fiddle. I don't have a bluetooth keyboard so I can't test it. Sorry if it doesn't work.

$(document).keydown(
function (event) {
        var keyCode = event.which;
        document.getElementById("keydisp").innerHTML = "key pressed: " + keyCode;
});

$("input").keydown(
function (event) {
        var keyCode = event.which;
        document.getElementById("keydisp").innerHTML = "key pressed: " + keyCode;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

<input type="textarea" id="input" autocorrect="off" autocapitalize="off" style="width: 600px;">
<div id="keydisp" style="width 600px; height: 50px"></div>
Gokhan Kurt
  • 8,239
  • 1
  • 27
  • 51
  • Tested this. I get key down messages for alpha numeric keys and so on, but not the arrow keys. When the text input field has focus, the up arrow positions the text caret to the start of the text and down arrow positions the caret to the end of the text. – Sean N. May 31 '16 at 22:51
  • Ok, whoever downvoted this, can you explain yourself. Other answers don't even address the problem and say something completely irrelevant with the question. What might be my flaw that is bigger than theirs? – Gokhan Kurt Jun 01 '16 at 05:50
  • The input event doesn't trigger with the arrow keys on the ipad. – Josué Zatarain Sep 05 '18 at 14:57