Question

I'm building a medium-sized "single-page" JavaScript application using jQuery. If you include all possible functionality of the application, there are 134 click bindings.

Since most of the content is dynamically loaded, I can't just do this:

$(element).click(function() { ... });

Instead, I'm doing this:

$(document).on('click', selector, function() { ... });

Currently, I'm binding all of these on $(document).ready. But is that bad practice? Is this a speed issue?

The alternative would be to bind the event listeners every time the content is loaded, for example:

$('#content').html(...);
$('#newcontent').click(function() { ... });

The problem with that is it's difficult to organize. What advice can you give me?

Was it helpful?

Solution

You would get a slight increase in performance if you were to bind the events closer to the targets. As it is now every element within the document is being checked to see if it matches "selector". For instance, if your page is organized like this:

<div id="container">
   <div id="content">...</div>
</div>

You would be better off rewriting

$(document).on('click', selector, function() { ... });

as

$("#container").on('click', selector, function() { ... });

You would achieve the same convenience of not having to re-attach the events, but the action events would be limited to "#container". Another thing to consider with attaching events to $(document) is that if new items are added elsewhere on the page with the same selector you won't have to worry about them taking on unwanted behaviors.

OTHER TIPS

I believe you're doing it the preferred way (using on).

No real work is being done at $(document).ready ... you're just saying "bind me to any click event from any child element bubbling up to the document".

From a perf perspective, I would just make sure your selector is efficient.

The documentation (http://api.jquery.com/on/) shows binding at the <body> level rather than document, but that might be negligible.

What is best to do really depends on the details of the application, and will vary depending on the specifics of each application.

I find it is easier to follow the logic of an application with a single:

$(top).on('click', selector, function() { ... });

rather than have to discover that various part of the application add handlers as they update the part of the page they are responsible for. Note I've used top rather than document, because (like user12415 pointed out) it is better to use an element which is only as wide as needed rather than document itself.

I some cases, trying to add the handlers on directly on the elements themselves rather than use delegation can cause a significant performance hit or require stronger coupling between parts than what is desirable. I have an editing application where I use delegation to handle all click events on hyperlinks. This application has an editing core that provides the base functionality but uses modes to change editing behavior depending on what data is being edited. For instance, a mode could provide a facility to turn all instances of a word into a hyperlink to the same word in Wikipedia. The core cannot predict how a mode will change the document. So without delegation, the core would have to check every transformation to see whether it added a hyperlink, which is costly. A mode could turn plain text into hyperlinks as the text is being keyed in. So this would mean performing the check for every keystroke. Very costly! Or the mode would have to have a way to tell the core that it added to the document something that the core cares about. This is error prone. ("Oops! Forgot to tell the core.") Delegation is the sane option here.

Licensed under: CC-BY-SA with attribution
scroll top