Why 'onkeydown' callback is fired before 'onclick'? - javascript

There is the following code:
<div onkeydown="console.log('onKeyDown')">
<button onclick="console.log('onClick')">Test onClick</button>
</div>
If I tab to the button and press Enter I'll see 2 messages: 'onKeyDown' at first and 'onClick' at second. Why does 'onkeydown' event fire before 'onclick' event? I thought that 'onclick' event must bubble firstly.

Click is considered a "KeyPressed" event - keydown and keyup event completed - by JavaScript. Thus when you "begin" to click - by depressing the mouse button, for instance, the onkeydown event will trigger, before the click is released, at which point an onKeyUp event will be registered, and the two events taken together will also trigger an onKeyPressed event.
So browsers will register and process onKeyDown before waiting for the key to be released, at which point an onKeyUp event will be registered and processed.
See https://www.mutuallyhuman.com/blog/keydown-is-the-only-keyboard-event-we-need/ if this explanation is unclear.

Related

Backspace event troubles

I have an event listener on page 1
window.addEventListener("keydown")
It's causing me issues where another event listener "keydown" in a dialog on that page 1 is conflicting with the window event listener.
There are two event listeners:
dialog event listener
Page event listener
When I add text to the dialog, the page picks up that keydown. I don't want that. I can't add stopPropagation to the page then the dialog won't get the backspace.
What should I do? Can I replace the window. part to something more specific?
In your event handler for the text input, call event.stopPropagation() to prevent the event from being propagated further to other listeners.
https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

How to determine ordering of event listeners in Javascript

I'm confused by the ordering of event listeners in Javascript. If I have a form with a submit button and I'd like to alert a user instead of automatically submitting the form, but only when the submit using the Enter key, I can create an event listener for an Enter keypress, event.preventDefault(), etc.
Why is it that the default onsubmit event listener for the form is not triggered first?
Events do follow the law of causality. Smaller primitives build up larger, more important ones:
keydown -> keyup -> keypress -> change
mousedown -> mouseup -> click -> submit
In your case, the Enter keypress event causes the submit event.
Preventing the default action of an event will suppress the ensuing ones. They can't happen in reverse.

onblur vs onclick timing

There is a textarea element which converts itself into a div when onblur event happens on that same textarea. There is also a button which has its onclick property set to function f.
If one is writing in the textarea and then clicks on a button, f is fired, but also onblur event handler is triggered. Is there some order rules in this case, or the two handler functions may fire in random order?
I created a jsfiddle here: http://jsfiddle.net/z5SEp/
The events for latest Chrome seem to be:
mousedown
blur
mouseup
click
Although I could not find any documentation to rely on, it would make sense to me that blur is fired after mousedown, but before mouseup. Mousedown causes blur, but you could leave your mouse button down for an extended period of time and still cause a blur.
The order of click events will always be 1. mousedown 2. mouseup 3. click. The blur makes sense to be after mousedown but before mouseup.
More things to keep in mind
If you trigger the button click like this: $('button').trigger('click');, then the blur event will not fire, and focus will remain on the textarea.
In this scenario, the blur will always fire first because blur is triggered as soon as the mouse button goes down elsewhere on the page. So when the mouse goes down on your button, the textarea's blur event is fired first. As the mouse comes up, the button's click event is fired.

How do I avoid multiple key up/down/press events when holding a key?

I'm creating a web front end to control a small robot. Ajax calls will be made on a keydown, to start the robot, and keyup to stop it.
My problem is that when a key is held down the keyup, keydown, and keypress events seem to cycle continually. Does anybody know of a way to only have keydown fire when the key is first pressed and keyup to fire when it has been released?
--edit: I forgot to mention it originally but I have tried saving the state of the button. The problem is that keydown, keypress and keyup events fire over and over again as I am holding the key down.
I cannot reproduce the problem-
I do not find any keyup events thrown from keydown,
no matter how long I hold down a key.
This method listens for a keydown, runs some code,
and waits for a keyup before listening for another keydown.
The alert is only called on a keyup.
var A=[], who=// I used a textarea, substititute your own target
who.onkeydown= who.onkeyup= function(e){
e=window.event || e;
var t= e.type, target= e.target || e.srcElement;
A.push(t);
if(t== 'keydown'){
// start robot and stop listening to keydown
target.onkeydown= '';
}
else if(t== 'keyup'){
// stop robot and listen for keydown
target.onkeydown= arguments.callee;
alert(A)
}
}
You could try saving the state of the key. When the key goes down, check if the key is already pressed, if not, start the robot and mark the key as pressed. If it's already pressed, don't do anything. On key up, do the same thing for stopping the robot and mark the key as not pressed.
When you start your robot, remove the event handler from the keypress event and add an event handler for the keyup event to stop the robot.
When your keyup event fires, stop the robot and add you keypress handler back.
EDIT: By actually removing the event handler from your keydown event. You'll want to use the keydown and keyup events... not the keypress.
So basically:
assign keydown event handler
assign keyup event handler
on keydown, remove the keydown event handler and start your robot
on keyup, re-assign the keydown event handler

Javascript: invoke default keydown event handler

I'd like to invoke default keydown event handler from javascript. Is it possible?
If the event has an explicit event handler you can just invoke it directly:
// Precondition - the element has an explicit handler registered
element.onkeydown();
Otherwise, there's no way to explicitly tell the browser to do "what it would have done anyway". The only way to get this to happen is to not stop the event from bubbling - which can be a real pain if you want to set a timeout and then allow the event to continue, it's essentially not possible.
In most cases, though, you can invoke your own code on an event handler and let the keyDown event continue to the browser. And if this isn't possibel for whatever reason, you can usually write your own method that will simulate the effects of the event (e.g. change the content of an input field, submit the form, etc.)
There is no default keydown event. The keydown event occurs when the key is pressed on any form elements, followed immediately by the keypress event, and possibly the textInput event on text box when you enter a value. Then the keyup event is generated when the key is released
The following example shows the use of the onKeyDown event handler to display a message in the text box.
<body><form action="" method="POST" id="myForm"><input type="text" name="myText" onKeyDown="changeVal()"><script type="text/javascript" language="JavaScript">s1 = new String(myForm.myText.value)function changeVal() { s1 = "You pressed a key"
myForm.myText.value = s1.toUpperCase() }</script></form></body>

Categories

Resources