handleEvent Demo
Prepared for
https://dev.to/aman_singh/are-you-sure-you-know-how-event-propagates-in-javascript-2ojn
by Peer Reynders
HTML
<!-- component -->
<div>
<div class="grandparent js-grandparent">
<div class="parent js-parent">
<button class="click-me js-click-me">Click me!</button>
</div>
</div>
<hr>
<!-- options-->
<label><input type="checkbox" /> Stop Propagation on Capture (red div)</label>
<label><input type="checkbox" /> Stop Propagation on Bubble (blue div)</label>
<label><input type="checkbox" /> Stop Propagation on Click (button)</label>
<button>Clear Log</button>
<!-- end options-->
<!-- log-->
<textarea readonly></textarea>
<!-- end log-->
</div>
<!-- end component-->
<!--
DOM handleEvent: a cross-platform standard since year 2000
https://webreflection.medium.com/dom-handleevent-a-cross-platform-standard-since-year-2000-5bf17287fd38
EventListener.handleEvent()
https://developer.mozilla.org/en-US/docs/Web/API/EventListener/handleEvent
Using handleEvent with React
https://medium.com/@trukrs/using-handleevent-with-react-a75a6dc1fe16
-->
CSS
button {
display: block;
margin: 0.2rem 0;
}
label {
display: block;
}
textarea {
width: 100%;
height: 19rem;
}
.grandparent {
padding: 0.8rem;
border: 2px solid red;
}
.parent {
padding: 0.8rem;
border: 2px solid blue;
}
.click-me {
margin: 0 auto;
}
JavaScript
function clickGrandparent(log, stop, e) {
log('Handling click via capture on red div');
console.log('Red Div onClick');
if (stop) e.stopPropagation();
}
function clickParent(log, stop, e) {
log('Handling click via bubble on blue div');
console.log('Blue div on Click...');
if (stop) e.stopPropagation();
}
function clickButton(log, stop, e) {
log('Handling click directly on button');
console.log('Directly on button.. on Click...');
if (stop) e.stopPropagation();
}
function makeListener(refs) {
let stopGrandparent = refs.stopGrandparent.checked;
let stopParent = refs.stopParent.checked;
let stopClick = refs.stopClick.checked;
const log = (msg) => {
const current = refs.log.value;
refs.log.value =
current.length > 0 && msg.length > 0 ? current + `\n` + msg : msg;
};
return {
handleEvent(e) {
switch (e.currentTarget) {
case refs.grandparent:
if (e.type === 'click') clickGrandparent(log, stopGrandparent, e);
break;
case refs.parent:
if (e.type === 'click') clickParent(log, stopParent, e);
break;
case refs.clickMe:
if (e.type === 'click') clickButton(log, stopClick, e);
break;
case refs.stopGrandparent:
if (e.type === 'change') stopGrandparent = e.target.checked;
break;
case refs.stopParent:
if (e.type === 'change') stopParent = e.target.checked;
break;
case refs.stopClick:
if (e.type === 'change') stopClick = e.target.checked;
break;
case refs.clear:
if (e.type === 'click') log('');
break;
}
},
};
}
function initialize(grandparent) {
const root = grandparent.parentElement;
const parent = root.querySelector('.js-parent');
const clickMe = root.querySelector('.js-click-me');
const [stopGrandparent, stopParent, stopClick] = Array.from(
document.querySelectorAll('input[type="checkbox"]')
);
...