I have a div with a child element. I want to handle clicks on that specific parent div. Problem is, if I press mouse button while on child content and release it on parent, that still counts as click on parent. I want to handle only clicks that both started and ended on parent, while preserving capability for child to handle it’s own clicks.
document.querySelector('.clicker').addEventListener('click', () =>
alert('background was clicked')
);
document.querySelector('.child').addEventListener('click', event => {
alert('content was clicked');
event.stopPropagation();
});
.clicker {
background: #DADADA;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px;
text-align: center;
gap: 20px;
user-select: none;
}
.child {
background: white;
width: 100px;
height: 100px;
display: flex;
align-items: center;
justify-content: center;
}
<div class="clicker">
<div class="child">
Press left mouse button here
</div>
then release it here
</div>
Here it is in a fiddle:
https://jsfiddle.net/xs9za2j5/11/
Is there non-hacky way to do that, without individual handling of mousedowns and mouseups?
2
Answers
Try this:
The mousedown event sets the
isMouseDown
flag totrue
, indicating that the mouse button is being pressed. Themouseup
event then checks if theisMouseDown
flag is still true, which means that the mouse button was both pressed and released on the parent. If so, it triggers the background click alert. The child’s click event handler checks ifisMouseDown
is false, indicating that the mouse button was not pressed and released on the parent, and only then triggers the content click alert. Theevent.stopPropagation()
prevents the content click from propagating to the parent.It worked for me when I replicated your problem.
Hope I helped.
Use
Event.target
property to determine what is clicked at "mousedown" and "mouseup".Details are commented in example