I have a seemingly trivial problem but cannot find the cause. There is a minimal html structure:
<div id="bg">
<div id="panel"></div>
<div id="helper"></div>
</div>
Element #helper has display:none, and on mousedown event on #panel I set dipslay:block on #helper.
The problem can be described briefly like this: when I click inside element #panel, the click event always fires on element #bg, despite all effort to stop the event propagation on event handlers on #panel and #helper. I made a codepen to illustrate the problem:
https://codepen.io/tony124/pen/LYpQzwx?editors=1111
when I click outside of #panel, I get in console:
"onMouseDownBg" "bg" "bg"
"onMouseUpBg" "bg" "bg"
"onClickBg" "bg" "bg"
which is to be expected. However when I click on #panel, I get
"onMouseDownPanel (stop)" "panel" "panel"
"onMouseUpHelper (stop)" "helper" "helper"
"onClickBg" "bg" "bg"
which I cannot understand why. There is even no logging from onMouseDownBg and noMouseUpBg. How did the click event can ever fire?
It's about the order in which the events get called in and the actions taking place within the handlers.
onMouseDown
event:
onMouseUp
event:
onClick
event:
An element receives a click event when a pointing device button (such as a mouse's primary mouse button) is both pressed and released while the pointer is located inside the element. If the button is pressed on one element and the pointer is moved outside the element before the button is released, the event is fired on the most specific ancestor element that contained both elements. (emphasis mine)
In this case, the most specific ancestor element would be #bg, thus it handles the click event.
To get the effect you're probably looking for, just move the activation of the #helper element to the onMouseUpPanel
handler