The Beauty Of The jQuery Each() Method
Posted February 19, 2007 at 4:48 PM
The jQuery library provides a method, Each(), which will loop through each element of the target jQuery object:
Launch code in new window » Download code as text file »
- // Loop over each hottie.
- $( "#girls a.hottie" ).each(
-
- // For each hottie, run this code. The "indIndex" is the
- // loop iteration index on the current element.
- function( intIndex ){
-
- // Bind the onclick event to simply alert the
- // iteration index value.
- $( this ).bind (
- "click",
- function(){
- alert( "Hottie index: " + intIndex );
- }
- );
-
- }
-
- );
While there is nothing revolutionary going on here (although the "Bind" method is freakin' sweet-ass-sweet unto itself), the beauty of the Each() method is that it creates a separate function scope for each loop iteration. For anyone who has tried to do a standard FOR-Loop in which each iteration tries to dynamically set some object value, you probably have run into situation where all values post-loop are the same. This has to do with when the variable is being bound.
By creating a separate function scope for each loop iteration, you basically eliminate all the "unexpected" variable binding behavior. Sweet! It seems every time I step back and look at what jQuery is doing for me, it's simply stripping away more and more headache time.
Download Code Snippet ZIP File
Post Comment | Ask Ben | Other Searches | Print Page
Newer Post
jQuery And Ext Partner To Deliver Integrated JavaScript And UI Features
Older Post
Completely Awesome: Whack Your Boss
Reader Comments
Yes indeed, each() rules. If you get excited about this kind of stuff, you may want to take a look at Ruby on Rails if you haven't already done so. You'll get excited about a lot of things. For one, the Ruby language alone has some very powerful features that are quite unique and that allow for very elegant code. I really like ColdFusion, but I think RoR brings a lot to the table and it costs nothing (OK, I know, our time is valuable) to give it a try and see something different. And if you decide to do so, please be sure to let us all know what you thought!
Thomas,
Thanks for the heads up. To date, I have not looked into Ruby on Rails. However, I have heard a lot of good things about it. When I start to look into it, I am sure I will have a lot to say ;)
Great Code.
Thanks
exactly what i was looking for. this should be a jquery tutorial. thanks.
I like it, because of possiblity to work with associative arrays - it's really powerful!
Double thanks!
First - for Each(), another one - for $(this), both helped me a lot!
Wow. Thank you. I'm fairly new to js/jquery and this really helps me with logically thinking/looking at what I need. Plus it really helps me in a current project.
@Goody,
I think you are really gonna love jQuery. It rocks and will make Javascript development much easier!
Oh my, you just saved me what I'm sure would have been a few more hours of searching. The each() function is great but I couldn't find any documentation anywhere regarding getting an index from it until here. So thank you. I like jQuery but IE doesn't play nice.
Thanks for assuming that I don't exist
@A Geek Girl,
I am not sure what you are referring to?
hey
I want to use each() to manipulate all the checkboxes that match.
my head and the wall are both bloody now, i seem to need to use this.checked i.o. $(this)
typeof($(this)) yields 'object object'
anyone care to enlighten me?
$('.myclass').each(
function ( intindex ){
this.checked =chkbox.checked ;
}
);
does work. (thanks alot for that btw). Just trying to understand why it works, lol.
how does my function know what this is? i have lots of user myths building up in my head....
thanks again
@greg,
When jQuery executes the function that you pass to the each() method, it executes it in the context of given object such that "this" is explicitly pointed to the given object. This is what the call() and apply() methods do in Javascript.
Most likely, they do something like this:
for (i = 0 ; i < this.size() ; i++){
. . . . yourCallback.call( this[ i ], i, this[ i ] );
}
The first argument of the call() method is the this/context of the executing function (yourCallback). Any subsequent arguments (i, this[ i ]) are the actual arguments passed to the method.
Thanks for this.
You're a Funkin Guy... Everythin I search in google I get you blog... Thanks Ben!
@Roberto,
Ha ha, thanks man - just glad that I'm putting some good stuff out tehre.
This is some real good stuff right here. You got to love Jquery
Hey Ben how are you?
very good stuff here, it helped to much...
Nice photos too...
Thanks
There is some functionality mistakes in this girl.hottie example.
plz replace alert with f***.
Thanks.
@ABCD
That would require that us programmers actually talk to girls, which (*adjusts glasses*) is simply ridiculous.
In seriousness, thanks for the write-up, Ben.
@George, @EFGH,
No problem guys, glad to help.
Hey Ben,
Good lookin' blog for a developer :P
Relating to each(), have you got any tips on not getting this outputting a 'continue reading' link for EVERY <p>, but the whole bunch of <p>'s in the post?
Example here: http://test.ldexterldesign.co.uk/?page_id=9 (disable CSS and you'll see what I mean: http://twitpic.com/gsxsk)
Thanks,
L
@Lewis,
I think the problem is that you are calling each() on your P tags. What you want to do is get the collection of P tag and then get the text() on the entire set.
var text = $( ".... p" ).text();
This will return the text aggregation of all the paragraphs found in the set. This way, you don't have to loop over the 2 paragraphs, which is why you are getting two read more links.
Wow! now i understand "each()"!! i've had read a lot about it, but using "common names"....but it was hard to understand.
With this example: "girls.hottie", was so really easy to understand hehehehe
thanks!
@A GEEK GIRL: hehehe
@ArthasMX,
Excellent - glad I could explain this in a way that finally made sense.
Hi, quick question: I'm using each() and I'd like to use the index as part of a selector, as in
$(".input").each(function (i) {
inputVal = $(this).getValue();
if (inputVal==null||inputVal =="") {
$(this).addClass('alertInputEmpty');
$('.fieldAlert').get(i).html('Please enter a valid path');
...
I can't for the life of me figure out how to get that last line to work. Any help would be greatly appreciated!
Thanks!
Dude, the choice of variable names is quite sexist, I hope your lady clients don't ever see this, as many will be quite put off (as I am)
@ A Lady
If anything it's an honor to your gender. It's a way of saying we worship you. I understand that since you're a woman you can't understand this, but it doesn't make it not true.
@A Lady, @Nick,
It's all in good fun. People only come to site if / when they want to :)
@Mike,
That should actually work, as far as I can see.
Hey, Ben! Thanks for the great article and don't worry about what "A Lady" says about it being sexist because it's not. Sometimes it's good to make the examples more fun as long as the content isn't blatantly offensive (some examples: swearing, referencing certain body parts, or adult images)..... This way your readers don't get into trouble at work when they look for a simple code example or want to check their syntax.
(That's just my humble opinion.)
Did you have to call:
$( this ).bind (
"click",
function(){
alert( "Hottie index: " + intIndex );
}
);
Couldn't you just call:
$( this ).click (
function(){
alert( "Hottie index: " + intIndex );
}
);
@Amy,
I appreciate your feedback :) Exactly, I'm just trying to keep the learning fun.
@Kristopher,
Yes, you can certainly use the event-name short hands; in fact, that's what I often use these days. If you want to define the event handler with additional data, however, you still need to use the bind method:
$( .. ).bind( "click", eventData, function(){} );
Other than that, though, there is zero downside to the short hand notations.
It was very useful but I wonder what to do in case you are not interested in all elements, but for example all minus 5 last?
@Marta,
You can start to limit the collection using the various selectors and filtering methods. For example, if you have 10 items in the child node collection, you could use the pseudo-selector :lt()
$( "span:lt(5)" )
My problem is that I work with an xml document which is weather data for a specific place.
<time period='2'> </ time>
<time period='3'> </ time>
<time period='0'> </ time>
<time period='1'> </ time>
<time period='2'> </ time>
<time period='3'> </ time>
<time period='0'> </ time>
<time period='1'> </ time>
<time period='2'> </ time>
<time period='3'> </ time>
Each <time/> equivalent to 6 hours of each day. As time 0-3 = 24h. When I take home my xml document, there are more days than I would like to in the form of </ time> nodes(3-1/day), and each xml document does not begin with period = 0, in the event period 0 has expired, there's just time = 1 and so on. So the solution you gave me does not help as much as all the combinations between 20 and 16 may be possible. I have now sat and figured the problem for several days, would need a kick in the butt to move forward in my project.
There is an example of the xml document I work with so it is perhaps easier to understand what I'm about woolly.
http://www.yr.no/sted/Sverige/Kalmar/Borgholm/forecast.xml
Excuse me for my English.
Best Regards Marta
@Marta,
Are you saying that the XML you are working with has bad data? I apologize, but I am not completely sure what you are asking. Are you trying to do this with jQuery? Or are you parsing the XML with some other language?
I have solved my problem now and can present my file using jQuery, thanks a lot.
@Marta,
Great - glad you got it working.




