I am trying to understand the the correct way of coding.
My HTML
<div id="foo">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
If I want to add class bar
to all the children divs of div foo
, which way should I use?
Option 1 (turned out 3rd)
jQuery( '#foo > div' ).addClass( 'bar' );
Option 2 (turned out 4th fastest)
jQuery( '#foo' ).children( 'div' ).addClass( 'bar' );
Option 3 (turned out the fastest)
jQuery( '#foo' ).children( 'div' ).each(function(){
jQuery( this ).addClass( 'bar' )
});
Option 4 (turned out very close 2nd)
jQuery( '#foo > div' ).each(function(){
jQuery( this ).addClass( 'bar' )
});
These all accomplishes what I want. My Question is,
Which one should I prefer using over the other? Which cases should I use .each
?
Edit with added snippet which shows using each is better than the other methords
var t0_start = performance.now();
$('#parent > div').addClass( 'bar' );
var t0_end = performance.now();
var t1_start = performance.now();
$('#parent').children('div').addClass( 'bar' );
var t1_end = performance.now();
var t2_start = performance.now();
$( '#foo > div' ).each(function(){
$( this ).addClass( 'bar' )
});
var t2_end = performance.now();
var t3_start = performance.now();
$( '#foo' ).children( 'div' ).each(function(){
$( this ).addClass( 'bar' )
});
var t3_end = performance.now();
outcome = 'selector: ' + (t0_end - t0_start);
outcome += "\n";
outcome += 'children(): ' + (t1_end - t1_start)
outcome += "\n";
outcome += 'selector: each(): ' + (t2_end - t2_start)
outcome += "\n";
outcome += 'children(): each(): ' + (t3_end - t3_start)
alert(outcome);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent"><div></div><div></div><div></div></div>
The result I got was time for selector: each() < time for children(): each() < time for selector: < time for selector: < time for children():
One way is to add a property using the dot notation: obj. foo = 1; We added the foo property to the obj object above with value 1.
The prototype property allows you to add properties and methods to any object (Number, Boolean, String and Date etc.).
Using the prototype object to add custom methods to objects The prototype object can also help you quickly add a custom method to an object that is reflected on all instances of it. To do so, simply create the object method as usual, but when attaching it to the object (you guessed it), use "prototype" beforehand.
UPDATE: The perf tests seem to be getting optimized at runtime and providing some weird numbers. I've broken the tests into separate snippets (iframes) to get more consistent numbers.
UPDATE 2: Here's a jsbin wherein I attempt to gain some insight. The selector method is on average faster, but there's overlap. http://jsbin.com/jiluzu/edit?js,output
UPDATE 3: jsperf.com is back up! It further supports "selector" as the faster method. http://jsperf.com/jq-selector-vs-children
ORIGINAL: In this particular scenario I'd use the first example. It's more succinct and saves you an additional function call. Also, nowadays the "selector" method is more performant as well.
$('#parent > div');
var start = performance.now();
$('#parent > div');
var end = performance.now();
outcome = "$('#parent > div'): " + (end - start);
$('#parent').append(outcome);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent"><div></div><div></div><div></div></div>
$('#parent').children('div');
var start = performance.now();
$('#parent').children('div');
var end = performance.now();
outcome = "$('#parent').children('div'): " + (end - start);
$('#parent').append(outcome);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent"><div></div><div></div><div></div></div>
$('#foo > div').each()
var start = performance.now();
$('#foo > div').each(function(){});
var end = performance.now();
outcome = "$('#foo > div').each(): " + (end - start);
$('#parent').append(outcome);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent"><div></div><div></div><div></div></div>
$('#foo').children('div').each()
var start = performance.now();
$('#foo').children('div').each(function(){});
var end = performance.now();
outcome = "$('#foo').children('div').each(): " + (end - start);
$('#parent').append(outcome);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent"><div></div><div></div><div></div></div>
When to use each()
Using each
is helpful in scenarios where you want to do some additional manipulations relative to each item selected.
For example, if we wanted to additionally add a class to the preceding element of each of the selected elements:
jQuery( '#foo' ).children( 'div' ).each(function(){
jQuery( this ).addClass( 'bar' );
jQuery( this ).prev().addClass( 'foo' );
});
With jQuery, option 2 and 3 are probably quite similar, other than with each()
you can perform more than one action per element in the selection using a function.
Option 1 is the least performant in older browsers like IE8, Chrome 5, Opera 9 with older versions of jQuery. This is because the CSS selector has to be parsed before making the actual selection, which is basically just going to call option 2 anyway.
Why you should never use CSS text selectors
$("#parent > .child");
and$("#parent .child");
both need to parse the selector and then just call:$('#parent').children().filter('.child')
and$('#parent').filter('.child')
respectively.
More info, including benchmarks for older browsers, here (from 2010).
The above is old news for modern browsers and jQuery. CSS selectors are faster nowadays.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With