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" />&nbsp; Stop Propagation on Capture (red div)</label>
  <label><input type="checkbox" />&nbsp; Stop Propagation on Bubble (blue div)</label>
  <label><input type="checkbox" />&nbsp; 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"]')
  );
...