'JS processing events happening parallel to listeners running
I am not sure, how events are generated while some JS code is running.
For example in this scenario:
<div id="div1"> text </div>
<div id="div2"> text </div>
div2.onpointermove = (e) => {
console.log("old handler");
};
div1.onpointerdown = (e) => {
div2.onpointermove = (e) => {
console.log("new handler");
}; };
Layout:
+-----+-----+
|div1 | div2|
+-----+-----+
Scenario:
- pointerdown on an edge pixel of
div1 - pointermove outside of
div1and intodiv2
While the JS code runs on a single thread, the user can move the mouse parallel to some JS code running. I would like to know, how events are generated and then processes, while some JS code is running?
Possible timelines:
A)
- pointer down on the edge-pixel of
div1 - move the mouse onto
div2parallel to the event listener JS code running - while the JS code processes the event listeners, the mouse events are queued
- invoke
div1.onpointerdown - add new handler
div2.onpointermove - the queued mouse events are processed with the new set of listeners
- "new handler" is printed on the console
B)
- pointer down on the edge-pixel of
div1 - move the mouse onto
div2parallel to the event listener JS code running - while the JS code processes the event listeners, the mouse events are ingored
- invoke
div1.onpointerdown - add new handler
div2.onpointermove - start to register events again
- the pointer move on
div2was lost, nothing is printed on the console (if the mouse did not move afterdiv1.onpointerdownhas finished processing, and JS did not compare the mouse position before-after processing the code-chunk)
C)
- pointer down on the edge-pixel of a
div1 - move the mouse onto
div2parallel to the event listener JS code running - while the JS code processes the event listeners, the mouse events are queued to be processed with the current, old set of event listeners
- invoke
div1.onpointerdown - add new handler
div2.onpointermove - process the next event from the queue with the old, recorded event listeners
- "old handler" is printed on the console
I don't know, which scenario will happen, or if it is browser-dependent?
The pointerdown, pointermove is only for the purpose of the example, I am not interested in the quirks of those exact events, rather the more general concept of how events are generated/saved/ignored/handled while some JS code is running which is adding event handlers for those event happening parallel to the code chunk running.
Also, if there is universal behavior, or there are implementation-specific details?
Solution 1:[1]
In general, approach A is used - events are queued, then processed once the JS event loop has finished execution of previous handlers.
However, fast and continuous (indiscrete) events like scrolling or mouse movement (as opposed to, say clicks or keypresses) can be throttled by the engine, so that it fires fewer of them if the JS code processing them takes a long time. This may amount to discarding some events (approach B) - but how you can you tell?
As for approach C, that is not used. It's the events that are queued, not the tasks to run the registered handlers. This is especially important when removing event listeners - after you call removeEventListener, you can be certain that it won't be called again, even if an event is still queued that would have triggered it. However, for installing new event listeners there's not really a way to tell the difference - the code cannot tell whether the event was fired before or after the listener was installed, so this gives browsers some leeway to optimise.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Bergi |
