This solution is generated by ChatGPT, correctness is not guaranteed.

AI solution for JavaScript Coding Question on BFE.dev
117. event delegation

Here's one possible implementation:

function onClick(root, predicate, handler) {
  root.addEventListener('click', function(event) {
    let el = event.target;
    while (el && el !== root) {
      if (predicate(el)) {
        handler.call(el, event);
      }
      el = el.parentNode;
    }
  });
  
  const stopPropagation = function(event) {
    event.stopPropagation();
  };
  
  const stopImmediatePropagation = function(event) {
    event.stopImmediatePropagation();
  };
  
  return {
    off: function() {
      root.removeEventListener('click', handler);
    },
    stopPropagation: stopPropagation,
    stopImmediatePropagation: stopImmediatePropagation,
    stop: stopImmediatePropagation
  };
}

Here's how it works:

  • We attach a single click event listener to the root element.
  • Inside the handler, we check if the clicked element (event.target) matches the predicate. If it does, we call the handler function with that element as the "this" context.
  • We then traverse up the DOM tree, testing each ancestor of the clicked element, until we hit the root element.
  • This allows us to use event delegation to handle clicks on multiple elements with a single event listener.
  • We return an object with two properties (stopPropagation and stopImmediatePropagation) which are functions that can be used to stop the propagation of events. We also include a "stop" function for convenience, which is an alias for stopImmediatePropagation.
  • Finally, we include an "off" function which can be used to remove the event listener if needed.