Main content
Computer programming
Course: Computer programming > Unit 7
Lesson 4: jQuery techniques- jQuery Collections vs. DOM Nodes
- Using jQuery variables
- Looping through jQuery collections
- Challenge: Loopy language
- Review: jQuery collections & looping
- Chaining jQuery methods
- Challenge: Daisy chain
- Behind the scenes: Browse the jQuery source code
© 2023 Khan AcademyTerms of usePrivacy PolicyCookie Notice
Review: jQuery collections & looping
jQuery collections
When you use jQuery to find elements, jQuery returns back a jQuery collection object:
var $heading = $('h1');
It is common practice to start variable names like that with a
$
sign to show that they're storing jQuery collection objects. That helps distinguish them from variables that store DOM nodes.If you'd like to retrieve the DOM node out of a jQuery object, then you can treat the jQuery object like an array and use bracket notation:
var heading = $heading[0];
If you'd like to turn a DOM node into a jQuery object, you can pass it into the jQuery function:
var $heading = $(heading);
Looping through collections
If you'd like to loop through multiple elements in a collection, you can use a normal
for
loop or jQuery's each()
: $("p").each(function(index, element) {
$(element).text( $(element).text() + "!!");
});
When you call the
each()
function, you must pass a 'callback function' to it. jQuery will then call that callback function for each element in the collection, and it will pass the current index and element to the function.jQuery will also set the context of the function to the current element, which means you can reference the element with the
this
keyword: $("p").each(function() {
$(this).text( $(this).text() + "!!");
});
Want to join the conversation?
- I don't understand what to do for loopy language??(20 votes)
- You want to loop through the p tags (not the individual words) and apply
toPigLatin()
on them. How you do that is you first loop through the p tags like this:var $paragraphs = $("p");
$paragraphs.each(function(index,element){
});
Then you need to make each element into a jquery collection objectvar $paragraph = $(element);
Then call toPigLatin on each paragraph like this:var $paragraphs = $("p");//find all the <p> tags
$paragraphs.each(function(index,element){//iterates through each paragraph
var $paragraph = $(element);//turns it into a jquery collection object so .text() will work
$paragraph.text( toPigLatin($paragraph.text()) );//change the text to pig latin
});(54 votes)
- For looping through collections, is it necessary to include (index, element) or is that just illustrating the parameters that will get called anyway and you can you just put ()?(7 votes)
- You can just use
function ()
and refer to the current element withthis
. You'd really only need the parameters if you needed to know the index too, and then you'd really only need the first one.
If a function in JS is defined with parameters and not called with parameters, or called with parameters and not defined with paramaters, they'reundefined
in the first case or just thrown away in the second case.
Sincethis
gets bound by jQuery, you can just not use or declare the paramaters.(9 votes)
- I wrote the code below but it does not work for last challenge. I cant figure out how and what to pass in to the toPigLatin function. I would really appreciate it if someone could look at code below and figure out what I am doing Wrong.
$paragraphs = $("p");
for (var i = 0;i < $paragraphs.length;i++) {
var element = $paragraphs[i];
var $paragraph = $(element);
var $done = toPigLatin $("$paragraph.text");
$paragraph.text($done.);
}(3 votes)- Instead of doing:
var element = $paragraphs[i];
var $paragraph = $(element);
Just usevar element = $($paragraphs[i]);
. It's better because you're using less variables, and that's better than using unnecessary variables. Also, you forgot to use thevar
keyword with$paragraphs = $("p");
, so JavaScript won't know what to do with it.
Also,var $done = toPigLatin $("$paragraph.text");
would cause an error because you're putting a$
in between the functiontoPigLatin
and the parentheses, so the JavaScript (remember, jQuery is used with JavaScript) can't run the function. Second of all, you put$paragraph.text
inside quotes, so JavaScript would just treat it as a string, and not run it as code.
Last of all,$paragraph.text($done.);
has one problem, you put$done.
inside the parentheses, so JavaScript will think that you're trying to find a values within the Object (in this case:$done.
), but you didn't put anything after the dot, so JavaScript won't know what to do, also, you're not even wanting to call from an Object here, well here's the code for the challenge:var $paragraphs = $("p");
for(var i = 0;i < $paragraphs.length;i++) {
var element = $($paragraphs[i]);
element.text(toPigLatin(element.text()));
}
Good luck and happy coding!(10 votes)
- The fact that you use TWO diff variables "paragraphs" PLURAL and then " paragraph" SINGLE tripped me up. SO i don't get how the single one knows anything about the plural one?(3 votes)
- The plural contains the collection or array, the singular contains the current array item(3 votes)
- I noticed that in the Looping through jQuery collections video (around), Pamela used several lines of code to loop: 3:46
var $paragraphs = $("p");
$paragraphs.each(function(index, element) {
var $paragraph = $(element);
$paragraph.html( $paragraph.html() + "..wowee!");
});
But in this review page, we're shown that we can use a bit of shorthand:$("p").each(function() {
$(this).text( $(this).text() + "..wowee!");
});
(Please correct my code if I made a mistake somewhere!)
Anyway, my question was: is it better to use more code or less, or does it depend? I can see that it would be much more efficient to use less code, but more self-commenting and human-friendly to use more. And another benefit of naming variables might be to access them more easily if the code is more complex. What are other considerations coders might have?(2 votes)- You've pretty much summed it up.
The only thing I might add is that if you use variables, you can reuse them if necessary.(3 votes)
- Loopy Language Challenge. I am not getting it. Need some direction. I am doing this:
// Iterate through each paragraph, call the toPigLatin function on it
var $paragraphs = $("p");
for (i = 0; i < $paragraphs.length; i++) {
var element = $paragraphs[i];
toPigLatin("element");
}
Nothing happens to the text.(1 vote)- you can set element back to a jquery collection using
var paragraph = element;
Then apply the method to the text using
paragraph.html(toPigLatin(paragraph.html()));
this sets the paragraph innerHTML to a piglatinized version, as paragraph.html() is the current html of the element.(1 vote)
- for Loopy language, I did:
var $paragraphs = $("p");
$paragraphs.each(toPigLatin);
I received a runtime error that str.replace (from the toPigLatin function) was not a function.(1 vote).each()
iterates through a jQuery collection. You must pass it a callback function that is written to operate on the context of a DOM node.toPigLatin
in it of itself does not modify text of a DOM node, so using it as your callback function does not help you achieve what you want.(4 votes)
- can you explain about callback function ..(2 votes)
- Callback function is normal function is just called later by another function using its passing parameters. Here is visual explanation where
method
is parameter where its function get callback as*method()*
:var add = function( a, b, method ){
if(method){
var c = method();
return (a+b)+c;
}else{
return a+b;
}
}
add( 2, 3 ); // returns 5
add( 2, 3, function(){return 7;} ); // returns 12
now you see similar features in
$("p").each(function(index, element) {
$(element).text( $(element).text() + "!!");
});
I know, you would say why they wouldn't name as it is?! less confusion, right! like passing function instead of callback, may be passing would sound funny like passing fart ;)(1 vote)
- Sorry if this is an obvious question but why is it called DOM nodes?(2 votes)
- In the "HTML/JS: Making webpages interactive" tutorial, Pamela says that DOM stands for Document Object Model.
This is a video where she explains DOM nodes in more detail: https://www.khanacademy.org/computing/computer-programming/html-css-js/js-and-the-dom/pt/the-dom-document-object-model(1 vote)
- How does the toPigLatin function from the last challenge work?
var toPigLatin = function(str) {
if (!str.replace) {
return 'ERROR: Expected a string!';
}
return str.replace(/\b(\w)(\w+)\b/g, '$2-$1ay').toLowerCase();(1 vote)- The first three lines of the function is an
if
statement. It checks ifstr.replace
is not existent. Every value can be converted into a Boolean, simply with this logic: if the value is one of (undefined, null, "", NaN, false, 0), then the value isfalse
as a Boolean. If it is not one of those values, then it istrue
as a Boolean.
A string value has areplace()
method, and a function is not one of those Boolean-falsify values. So, it would return true. But, there's a!
there, which returns the opposite.
The opposite of true (str.replace) is false.
If str.replace is oneof the fake values, then it will escape the function withreturn
. Besides giving back a value,return
can escape the function.
The last line callsstr.replace()
, and passes it a regular expression. Regular expressions are used to perform complex search patterns.(2 votes)