I have the following situation:
My user presses and holds the left mouse button on element 1 and releases the mouse button on element 2. This emits a click on the wrapping element. This click should not happen, because the click on the wrapper executes another action, so i can not ignore the click completely on the wrapper.
Even when i use preventDefault or stopPropagation the click is emitted. See my example:
const wrapper = document.getElementById('wrapper');
const one = document.getElementById('one');
const two = document.getElementById('two');
const preventDefault = document.getElementById('preventDefault');
const stopPropagation = document.getElementById('stopPropagation');
const clear = document.getElementById('clear');
clear.addEventListener('click', () => console.clear());
const subscribe = (element) => {
const eventHandler = (event) => {
console.log(event.defaultPrevented ? 'prevented' : '', event.type, 'on', element.id);
if (preventDefault.checked) {
event.preventDefault();
}
if (stopPropagation.checked) {
event.stopPropagation();
}
};
element.addEventListener('mousedown', eventHandler);
element.addEventListener('mouseup', eventHandler);
element.addEventListener('click', eventHandler);
};
subscribe(wrapper);
subscribe(one);
subscribe(two);
.container {
border: 1px solid gray;
background-color: lightgray;
}
.toolbar {
position: absolute;
right: 1rem;
top: 2rem;
display: flex;
flex-direction: column;
}
#wrapper {
position: relative;
width: 250px;
height: 150px;
}
#one,
#two {
position: absolute;
width: 50px;
height: 50px;
background-color: blue;
color: white;
}
#one {
left: 50px;
top: 50px;
}
#two {
left: 150px;
top: 50px;
}
Click an hold left mouse button on 1 and release it on 2. Always a click is emitted on wrapper.
<div class="container" id="wrapper">
wrapper
<div class="container" id="one">1</div>
<div class="container" id="two">2</div>
</div>
<div class="toolbar">
<button id="clear">clear</button>
<label>
<input type="checkbox" id='preventDefault'>
preventDefault
</label>
<label>
<input type="checkbox" id='stopPropagation'>
stopPropagation
</label>
</div>
2
Answers
A
click
event is only emitted on elements if themousedown
andmouseup
happened within this element. You are creating amousedown
on 1 and amouseup
on 2. Thewrapper
element on the other hand receivesmousedown
,mouseup
andclick
You mentioned that you cannot completely ignore the click on the wrapper element, so I assume you want to perform different actions for clicks on
element 1
andelement 2
while still allowing some action to occur when a click happens on the wrapper. You can achieve this by checking which element was the target of the click in your click event handler.With this code, you can differentiate between clicks on
element 1
,element 2
, and the wrapper and perform different actions as needed. The wrapper’s click event will still occur, but you can handle it separately inside thehandleClick
function.