Question

As we all know, since jQuery 1.7:

$('someSelector').live('click', fn());

has become, essentially:

$(document).on('click', 'someSelector', fn());

All live events aren't directly bound to the elements in the selector, but delegate bound to the document.

This, I assume, is because elements that would match 'someSelector' in the future, aren't present in the DOM, so can't have event handlers bound (via direct or delegate binding).

For single page applications where the vast majority, if not all elements are dynamically loaded, are there published guidelines about how best to handle the issue of performance with binding everything to the document?

Covering, for instance, the best way to register/re-register event handlers when new content is loaded via ajax() and how to update code written in the lazy .live() mindset?

Was it helpful?

Solution

I'm not sure whether there are "published guidelines".

I think this approach has its merits:

  • Find the closest logical common ancestor that will not be deleted from the document.

    Example: For draggable table row behavior, this would be the parent table (or tbody).

  • Bind events there. This allows you to have separate instances of the same thing behave differently without the need for a context check.

    Example: If row-dragging is disabled temporarily on one of your tables, the table that handles the event would know, naturally. The document would not.

  • It would keep the number of events that are handled by document at a minimum, so there would not be many "is this really necessary" checks when an event occurs.

    Example: If there currently is no table with draggable rows, there is no need that an event handler even fires at the document level (just to find out that table.draggable tr wasn't really the source of the event and dismiss it immediately).

  • If the common ancestor gets removed frequently, you can decide whether re-binding the event handlers upon its creation or binding them a few levels up in the hierarchy would be better.

I would re-bind container events upon container creation, but that's personal preference, I presume. Re-binding is easy enough, after all:

// once, beforehand
var draggableTableRowBehavior = {
  dragstart: function () { /* ... */ },
  dragstop: function () { /* ... */ }
  /* ... */
};

//in Ajax success:
$table.on(draggableTableRowBehavior, 'tr');
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top