title: Most efficient way to dynamically bind event handlers
body: <p><strong>Problem:</strong> I need to bind any number of event handlers to any number of elements (DOM nodes, <code>window</code>, <code>document</code>) at dynamically runtime and I need to be able to update event binding for dynamically created (or destroyed) nodes during the lifetime of my page. There are three options that I can see for tackling this problem:</p>
  
  <p>I) Event delegation on <code>window</code><br>
  II) Direct event binding on each node<br>
  III) Event delegation on common ancestors (which would be unknown until runtime and would potentially need to be recalculated when the DOM is altered)</p>
  
  <p>What is the most efficient way of doing this?</p>
  
  <h2>A little context</h2>
  
  <p>I am working on a set of pages that need analytics tracking for user events (clicks, scrolling, etc.) and I want to be able to easily configure these event handlers across a bunch of pages without needing to write a script to handle the event binding for each instance. Moreover, because I may have the need to track new events in the future, or to track events on elements that are dynamically added to/removed from the page, I need to be able to account for changes in the DOM that occur during the lifetime of the page.</p>
  
  <p>As an example of what I'm currently considering, I would like to create a function that accepts a config object that allows the programmer to specify default handlers for each event, and allow them to override them for specific elements:</p>
  
  <pre><code>Analytics.init({
      // default handlers for each event type
      defaultHandlers: {
          "click": function(e) { ... },
          "focus": function(e) { ... }
      },
  
      // elements to listen to 
      targetElements: {
  
          // it should work with non-DOM nodes like 'window' and 'document'
          window: {
              // events for which the default handlers should be called
              useDefaultHandlers: ['click'],
  
              // custom handler
              "scroll": function(e) { ... }
          },
  
          // it should work with CSS selectors
          "#someId": {
              useDefaultHandlers: ['click', 'focus'],
              "blur": function(e) { ... }
          }
      }
  });
  </code></pre>
  
  <h3>Sources</h3>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/12824549/should-all-jquery-events-be-bound-to-document">SO: Should all jQuery events be bound to document?</a></li>
  <li><a href="https://stackoverflow.com/questions/3960843/how-to-find-the-nearest-common-ancestors-of-two-or-more-nodes">SO: How to find the nearest common ancestors of two or more nodes</a></li>
  <li><a href="http://api.jquery.com/on/" rel="nofollow noreferrer">jQuery docs: $.fn.on()</a></li>
  </ul>