DEV Community

loading...

Discussion on: Are you sure you know how event propagates in JavaScript?

Collapse
peerreynders profile image
peerreynders • Edited

Peculiar how React's synthetic event system ignores the handleEvent portion of the EventListener interface which allows objects to listen to events.

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"]')
  );
  const clear = root.querySelectorAll('button')[1];
  const log = root.querySelector('textarea');
  const refs = {
    parent,
    grandparent,
    clickMe,
    stopGrandparent,
    stopParent,
    stopClick,
    clear,
    log,
  };

  const listener = makeListener(refs);

  grandparent.addEventListener('click', listener, { capture: true });
  parent.addEventListener('click', listener);
  clickMe.addEventListener('click', listener);
  stopGrandparent.addEventListener('change', listener);
  stopParent.addEventListener('change', listener);
  stopClick.addEventListener('change', listener);
  clear.addEventListener('click', listener);
}
Enter fullscreen mode Exit fullscreen mode

JS Fiddle

Seems Preact is looking into adding support for it (see also radEventListener: a Tale of Client-side Framework Performance).