How can I determine if a bubbling event was already handled before.
I want to handle a click event that was performed on a .card
element. The event handler should trigger a click event on the first link in that card. If the user clicks on the second link in that card, the card's event handler should do nothing.
So I want to find a way, if any event handler (built-in or custom, including those that I have no control over) was called before.
Edit
This is not a question about a specific issue I have, but a general question on DOM event handling.
Edit 2
For popular demand (1 comment :) ) I'll add some example code.
This example will not fully work, as there are restrictions to links in SO snippets. I have a fully working example on Codepen
;
(function () {
var selectors = []
var subs = []
function triggerMouseEvent(
event,
target,
options
) {
options = Object.assign({
view: window,
bubbles: true,
cancelable: true
}, options)
const e = new MouseEvent(event, options)
setTimeout(function () {
target.dispatchEvent(e)
}, 10)
}
function delegateClick(selector, subSelectors) {
var selector = selectors.push(selector) - 1;
var sub = subs.push(subSelectors) - 1;
return {selector,sub}
}
function undelegateClick({selector, sub}) {
selectors.splice(selector, 1);
subs.splice(sub, 1);
}
function evnt(e) {
selectors.forEach(function (selector, index) {
if (e.target.closest(subs[index].join(','))) {return}
var s = e.target.closest(selector)
if (!s) {return}
var selEl
subs[index].find(function (sub) {
return selEl = s.querySelector(sub)
})
if (selEl && e.target !== selEl) {
triggerMouseEvent(e.type, selEl, {
altKey: e.altKey,
ctrlKey: e.ctrlKey,
metaKey: e.metaKey
})
}
})
}
document.addEventListener('click', evnt)
// document.addEventListener('mouseover', evnt)
window.delegateClick = delegateClick
window.undelegateClick = undelegateClick
})();
dup = delegateClick('.card', ['a.act-on','button.act-on'])
.card {
margin: 20px;
border: 1px solid;
padding: 20px;
}
.card:hover {
background-color: gold;
cursor: pointer;
}
body {
display: flex;
}
<div class="card">
<h1>Click this card</h1>
<p>The action of the following button will be performed</p>
<button class="act-on" onClick="alert('Button pressed!')">Button!</button>
</div>
<div class="card">
<h1>Click this card</h1>
<p>The action of the following link will be performed <p>
<a class="act-on" href="https://example.org" target="_blank">example.org</a>
</div>
<div class="card">
<h1>Click this card</h1>
<p>The action of the following link will be performed</p>
<p>The link is preferred to the button</p>
<button class="act-on" onClick="alert('Button pressed!')">Button!</button>
<a class="act-on" href="https://example.org" target="_blank">example.org</a>
</div>
<div class="card" style="background-color: pink; border-color:red">
<h1>Click this card</h1>
<p><strong>If this button is pressed, the action of the link should not be done</strong></p>
<button class="dont-act-on" onClick="alert('Button pressed!')">Button!</button>
<a class="act-on" href="https://example.org" target="_blank">example.org</a>
</div>