title: Event delegation with vanilla js similar to JQuery's $.on
body: <p>I'm trying to delegate events like JQuery does with its <code>$.on</code> method, triggering events on targeted element and it's children (once when the targeted element has many children and could trigger too many times in events like mouseenter).</p>
  <p>I've created some examples of what I've achieved so far and the issues I couldn't solve.</p>
  <h1>Using <code>.matches</code>:</h1>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>"mouseenter mouseleave mouseup click".split(" ").forEach(eventType =&gt; {
    document.querySelector("#js-matches").addEventListener(eventType, function(event) {
      if (event.target.matches(".target")) showResult(event.type)
    }, true);
  });
  
  function showResult(result) {
    const resultBox = document.querySelector("#result")
    resultBox.innerHTML = result + '&lt;br&gt;' + resultBox.innerHTML
  }</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>body &gt; div {
    margin-right: 40px;
  }
  
  div {
    border: 1px solid;
    padding: 20px;
    background-color: white;
  }
  
  div:hover {
    border-color: yellow;
  }
  
  .target {
    cursor: pointer;
    background-color: red;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div id="js-matches"&gt;
    &lt;div class="target"&gt;
      &lt;div&gt;
        &lt;div class="content"&gt;Pure JS with matches&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div id="result"&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <ul>
  <li>Good: mouseenter and mouseleave are triggered only once;</li>
  <li>Bad: mouseup and click trigger only in the specified element, not in its children;</li>
  </ul>
  <h1>Using <code>.closest</code>:</h1>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>"mouseenter mouseleave mouseup click".split(" ").forEach(eventType =&gt; {
    document.querySelector("#js-closest").addEventListener(eventType, function(event) {
      if (event.target.closest(".target")) showResult(event.type)
    }, true);
  });
  
  function showResult(result) {
    const resultBox = document.querySelector("#result")
    resultBox.innerHTML = result + '&lt;br&gt;' + resultBox.innerHTML
  }</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>body &gt; div {
    margin-right: 40px;
  }
  
  div {
    border: 1px solid;
    padding: 20px;
    background-color: white;
  }
  
  div:hover {
    border-color: yellow;
  }
  
  .target {
    cursor: pointer;
    background-color: red;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div id="js-closest"&gt;
    &lt;div class="target"&gt;
      &lt;div&gt;
        &lt;div class="content"&gt;Pure JS with closest&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div id="result"&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <ul>
  <li>Good: mouseup and click are triggered in the targeted element and its children;</li>
  <li>Bad: mouseenter and mouseleave are triggered multiple times from targeted element to its children;</li>
  </ul>
  <p>Just to exemplify the desired behavior, here's the JQuery snippet:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>$("#jquery").on("mouseenter mouseleave mouseup click", ".target", 
    function(event) { showResult(event.type) }
  );
  
  function showResult(result) {
    const resultBox = document.querySelector("#result")
    resultBox.innerHTML = result + '&lt;br&gt;' + resultBox.innerHTML
  }</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>body &gt; div {
    margin-right: 40px;
  }
  
  div {
    border: 1px solid;
    padding: 20px;
    background-color: white;
  }
  
  div:hover {
    border-color: yellow;
  }
  
  .target {
    cursor: pointer;
    background-color: red;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"&gt;&lt;/script&gt;
  &lt;div id="jquery"&gt;
    &lt;div class="target"&gt;
      &lt;div&gt;
      &lt;div class="content"&gt;JQuery Box &lt;button&gt;Botão&lt;/button&gt;&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div id="result"&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>That's it, any tips will be helpful.</p>