问题
What is the best way to attach an event handler to element in jQuery by performance?
All elements that I want to attach an event handler to them, are static and we don't have any generated and dynamically created elements:
<div class="foo"></div>
<div class="bar"></div>
<div class="qux"></div>
I want to attach click
event handler to all them separately, I have three options.
I. Attaching event handler directly
In this classic method, I will attach the event handler directly to the elements:
$('.foo').on('click', f);
$('.bar').on('click', g);
$('.qux').on('click', h);
II. Attaching event handler to parent multiple times
In this method, instead of previous one, I'll attach the event handler to a parent one, multiple times, for each element:
$('body').on('click', '.foo', f);
$('body').on('click', '.bar', g);
$('body').on('click', '.qux', h);
III. Attaching event handler to parent just one time
This method is just like previous method, except one difference. I'll attach the event handler only one time, and I will check the desired selectors in the handler itself:
$('body').on('click', function (e) {
var $elem = $(e.target);
if ($elem.is('.foo')) { f(); }
else if ($elem.is('.bar')) { g(); }
else if ($elem.is('.qux')) { h(); }
});
I want to know which one is the best as performance?
回答1:
Decided to move it from comment to answer.
IMO, the operation of event binding does not affect performance much. What should be taken into account are operations, that are executed in the handler. That is why the third option is probably the worst.
The second option, AFAIK, is commonly used as event delegation. Mostly, in cases when you want to bind an event to the element, that would be created in the future, i.e. via AJAX:
$(document).on('click', '.futureElement', alert);
$.post("someurl", {data: someData}, function () {
//create element with class .futureElement
});
The first one is the common way of binding event with jQuery, therefore the fastest one of the presented.
回答2:
Your third solution is definitely the worst one, as it checks element's class whenever click event is fired.
The bottleneck here is jQuery selector parsing, so the first solution is the most efficent and readable one.
回答3:
Let me disagree with the other answers.
Even tests here http://jsperf.com/test-so-1 say that the last option is the fastest. But i can try to explain why.
In this case:
$('body').on('click', '.foo', f);
we use a standart jquery way to bind delegated events. We bind an event to the body
and ask jQuery to check it against .foo
selector. Each event has a property e.target
, which actually initiated the event. But event bubbles up the DOM so our .foo
selector can match one of the parents of e.target
. So jQuery must do additional traversing e.g. find all parents of e.target
and check it against .foo
selector.
It the 3d option we directly check only e.target
.
If .foo
selector is close to the body
then there is no much difference in performance. But if .foo
selector is deep inside the DOM tree jQuery have to traverse a lot of parents of e.target
.
Tests that demostrate it:
http://jsfiddle.net/xDyuJ/1/
http://jsfiddle.net/xDyuJ/2/
You can see it measures only events execution. The 3d case is more then twice faster. The gap will change relatively to the position on the elements in the DOM tree.
来源:https://stackoverflow.com/questions/16896435/best-way-to-attach-an-event-handler-to-element-in-jquery-by-performance