In my webpage I have a div, for which onkeydown event is handled. The onkeydown event is fired for keyboard keys character key 'z','a','p' etc. But the for the character key such as 'x','f','m','q' etc event is not fired . After pressing character key'f' I could see that the focus moves to the next element. Anyone please explain how this occur?
I could see the same happens in Chrome (version: 32) , IE (version:11) , Firefox (version:27)
Some keys might be used for some default operation by a browser. For example Enter submits a form in whitch the div is in IE. Try to use e.preventDefault(); before your own event code. Try the code below.
$(document).on("keydown", "mydiv", function(e) {
e.preventDefault();
});
Related
I have tried the W3 Schools example code for handling the enter key for input text. I copied the source code from that site's page and pasted below.
The problem is that on FireFox, if I press the enter key to finish Japanese input mode, the code is also triggered. On Edge, it did not. Is this a FireFox bug, or just a different behaviour? Anyway, how can I circumvent this?
var input = document.getElementById("myInput");
// Execute a function when the user presses a key on the keyboard
input.addEventListener("keypress", function(event) {
// If the user presses the "Enter" key on the keyboard
if (event.key === "Enter") {
// Cancel the default action, if needed
event.preventDefault();
// Trigger the button element with a click
document.getElementById("myBtn").click();
}
});
You should rather use KeyDown event. KeyPress is reporting every keycode from keyboard. Some keys on keyboard are not only putting one keycode but multiple keycodes. KeyDown event should pack all keycode from one actual pressed key into one event.
KeyPress is meant to do more low level approach
Note this question. I see that there are other approaches besides just triggering the tab keypress event, but I'd still like to know why triggering the tab key press event doesn't move focus to the next input field.
Code Pen
HTML
<textarea></textarea>
<textarea></textarea>
<textarea></textarea>
JS
$('textarea').on('keydown', function(e) {
if (e.metaKey && e.which === 40) {
console.log('test');
$(this).trigger({
type: 'keypress',
which: 9
});
}
});
Because the tab event is a native browser event/action for changing focus. The .trigger() function only triggers the event handlers that are assigned to it. Note there is more information given from jQuery's site:
The .trigger() function cannot be used to mimic native browser events, such as clicking on a file input box or an anchor tag. This is because, there is no event handler attached using jQuery's event system that corresponds to these events.
There is a plug-in for this though called jquery-simulate to handle this. That being said the tab key changing focus is actually a default action in the web browser. Firing a browsers native event does not mean it will do it's default action, as the documentation for KeyboardEvents mentions:
Note that manually firing an event does not generate the default action associated with that event. For example, manually firing a key event does not cause that letter to appear in a focused text input. In the case of UI events, this is important for security reasons, as it prevents scripts from simulating user actions that interact with the browser itself.
On a JavaScript page, I pop up an alert if the user hits the enter key by using
if(evt.keyCode == 13){
alert("Return Key Pressed");
}
but the event does not fire when I hit the return key on the iPad. How do I catch the event?
The iPad keyboard does fire the keypress event with a key code of 13 if you press return. This sounds like you've got something else going awry
Here's a quick jsfiddle to verify with: http://jsfiddle.net/359wG/
According to https://api.jquery.com/keypress/
The keypress event is sent to an element when the browser registers
keyboard input. This is similar to the keydown event, except that
modifier and non-printing keys such as Shift, Esc, and delete trigger
keydown events but not keypress events. Other differences between the
two events may arise depending on platform and browser.
A keypress event handler can be attached to any element, but the event
is only sent to the element that has the focus. Focusable elements can
vary between browsers, but form controls can always get focus so are
reasonable candidates for this event type.
I moved my return-key listener to an anchor tag, which on IPad is treated as a 'focusable element' similar to form controls.
I have an input field that I would like to validate on when the user either presses enter or clicks away from it, for this I use the events keypress and blur. If the input fails validation, an alert box is called.
I noticed that in IE (all versions), if I press enter with invalid input, for some reason both the keypress and blur events are fired (I suspect it's the alert box, but it doesn't do this on FF/Chrome) and it shows two of the same alert box. How can I have it so only one is shown?
EDIT: In FF/Chrome, I now noticed that a second alert box appears when I click anywhere after I try to validate with enter.
Simplified code:
$("#input-field").keypress(function(event) {
if (event.keycode == 13) {
event.stopPropagation();
validate();
return false;
}
});
$("#input-field").blur(function() {
validate();
});
function validate() {
if ($("#input-field").val() == '') {
alert("Invalid input");
}
}
EDIT: Ah-ha. Not really a fix but a separate detail I forgot - I need to restore the invalid input to its previously valid value, so when the validate function checks the value again it doesn't fail twice.
I ended up just checking for an IE UserAgent and skipping the keypress event for IE (binding keypress and blur to the same function, as below). Not a direct or terrific solution, tragically, but I've been looking to solve the same problem to no avail. Some minor notes that might be helpful: jQuery normalizes which, so you can confidently use e.which == 13 with keypress. I'd also combine the functions into one bind, e.g.
$("#input-field").bind('blur keypress', function(e) {
if(e.which == 13) {
// keypress code (e.g. check for IE and return if so)
}
validate();
});
I've tried setting globals and using jQuery's data() to assign arbitrary flags to indicate whether (in your case) validation has already been triggered for the element, but the events trigger simultaneously or at least, if sequentially, rapidly enough that even with an opening line setting some flag to true did not do the trick. I'd read that putting in a tiny callback delay might help, but that is hella dirty and I wouldn't do it even as a workaround so I've not tested it. stopPropagation() and preventDefault() also did not help.
Firefox does not get the keypress event right. Those events are only triggered when a key combination that produces a character is pressed (which is not the same as pressing any key).
Use keydown instead (as this is probably the only event IE handles correctly - as it should, since MS "invented" it ;-) ).
See http://www.quirksmode.org/dom/events/keys.html.
I'm listening for keypress events on an input field with delegation. For some reason, Firefox doesn't trigger the delegated event for cursor UP when at the start of the field, or cursor DOWN when at the end. LEFT and RIGHT work as expected all the time.
Directly binding an event listener to the field works fine, so it has to be something to do with delegation. Does anyone know if this is a know issue, I couldn't find anything on Google/forums etc..?
$("div").delegate(":input", "keypress", function(e){
// doesn't get triggered
});
$("div :input").bind("keypress", function(e){
// gets triggered fine
});
Here's a demo which shows the issue - http://livsey.org/jquery.delegation.html
These keys don't bubble in Firefox, at least not in that case, so .delegate() or .live() won't work. This is a known issue, better to use a different event in this case, like keydown or keyup, you can see the jQuery documentation for .keypress() for a quick blurb about this:
Note that keydown and keyup provide a code indicating which key is pressed, while keypress indicates which character was entered. For example, a lowercase "a" will be reported as 65 by keydown and keyup, but as 97 by keypress. An uppercase "A" is reported as 65 by all events. Because of this distinction, when catching special keystrokes such as arrow keys, .keydown() or .keyup() is a better choice.
Updating your code to this works:
$("div")().delegate(":input", "keyup", function(e){
log("delegated: "+e.keyCode);
});
$("div :input").bind("keyup", function(e){
log("bound: "+e.keyCode);
});