Short answer: definitely do it the first way. Event delegation is way more performant, but requires extra conditionals in your code, so it's basically a complexity versus performance tradeoff.
Longer Answer: For a small number of elements, adding individual event handlers works fine. However, as you add more and more event handlers, the browser's performance begins to degrade. The reason is that listening for events is memory intensive.
However, in the DOM, events "bubble up" from the most specific target to the most general triggering any event handlers along the way. Here's an example:
<html>
<body>
<div>
<a>
<img>
</a>
</div>
</body>
</html>
If you clicked on the <img>
tag, that click event would fire any event handlers in this order:
- img
- a
- div
- body
- html
document
object
Event delegation is the technique of listening to a parent (say <div>
) for a bunch of event handlers instead of the specific element you care about (say <img>
). The event object will have a target property which points to the specific dom element from which the event originated (in this case <img>
).
Your code for event delegation might look something like this:
$(document).ready(function(){
$('<div>').on('click', function(e) {
// check if e.target is an img tag
// do whatever in response to the image being clicked
});
});
For more information checkout Dave Walsh's blog post on Event Delegation or duckduckgo "event delegation".
NOTE ON CODE SAMPLE IN OP: In the first example, target.hasClass('editable')
means that the specific thing clicked on must have the class editable for the if block to execute. As one of the commenters pointed out, that's probably not what you want. You might want to try something along these lines instead:
$(document).on('click', function(e) {
if ($(e.target).parents(".editable").length) {
// Do whatever
}
});
Let's break that down a bit:
$(e.target)
- anything that on the page that was clicked converted to jQuery
.parents(".editable")
- find all the ancestors of the element clicked, then filter to only include ones with the class "editable"
.length
- this should be an integer. If 0, this means there are no parents with "editable" class