4

I am trying to get the html of "li" elements and alert them as a string.

HTML:

<ul>
    <li>lorem ipsum dolor <span>sit</span> amet 1</li>
    <li>lorem ipsum dolor <span>sit</span> amet 2</li>
    <li>lorem ipsum dolor <span>sit</span> amet 3</li>
    <li>lorem ipsum dolor <span>sit</span> amet 4</li>
    <li>lorem ipsum dolor <span>sit</span> amet 5</li>
    <li>lorem ipsum dolor <span>sit</span> amet 6</li>
</ul>

<p id="greeting">Hello <strong>World</strong>!</p>

Javascript:

$(document).ready(function(e){
    var list =  $("li");
    var greeting = $("#greeting");
    var content ="";
    for(var i=0, len = list.length; i<len; i++) {
        content += $(list[i]).html();   
        //why do I have to use the $ here instead of just doing list[i].html()

      //content += list[i].html(); why does this not work?
    }
    alert(content);
    alert(greeting.html());  //why does this work without the $ ?
});

I have done some research and understood that jQuery selectors return DOM elements wrapped in jQuery objects so that we can apply jQuery methods on it but why does the line greeting.html() work fine without the $?

TypeError: list[i].html is not a function

why do I get this error when I do list[i].html instead of $(list[i]).html()?

Here is the fiddle.

larrydalmeida
  • 1,570
  • 3
  • 16
  • 31
  • greeting returns a Jquery object with all it's functions. list returns a Jquery object as well, but since you used the "li" selecter it has multiple html DOMs. with li[i] you are now taking the single html DOM, without a Jquery object around it. That's why you have to use $(li[i]), to get the JQuery functions. – Danmoreng Oct 28 '15 at 12:11

3 Answers3

2

jQuery selections return a jQuery selection set (a "jQuery object"). That object is also an "array like" object meaning you can access the selection through indexer notation like in your example.

The elements in the selection set are dom elements and not jQuery selection sets themselves. If you want to convert a DOM element to a jQuery selection set you need to wrap it in $(yourElement).

var jQ = $("div"); // get all divs
jQ[0]; // the first div, a DOMElement
$(jQ[0]); // a selection containing the first div of the old selection
jQ.eq(0); // convenience for the above. 

The reason the API acts this way is for efficiency, if you selected 10000 divs, creating 10000 new objects is wasteful.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • `var jQ = ("div");` ..? Assuming you meant `$("div")`, `jQ.eq(0)` returns a jQuery object so no need of `$(jQ.eq(0));` – T J Oct 28 '15 at 12:15
  • @TJ I answered, saw a "possibly duplicate" flag a user left - and closed it - there were already answers when I posted. Duplicates get no attention and get deleted anyway - it takes it off the home page and makes other users not waste their time on it (voting or answering). – Benjamin Gruenbaum Oct 28 '15 at 12:21
  • Ah I see, Never mind then – T J Oct 28 '15 at 12:22
  • For efficiency! Kudos to the jQuery team! Thank you Benjamin. – larrydalmeida Oct 29 '15 at 04:41
0

They're stored as an array of HTMLElement wrapped as a single jQuery object.

If you wish to get one element you could use .eq():

content += list.eq(i).html();  
Curtis
  • 101,612
  • 66
  • 270
  • 352
0

Log $("li") and you'll understand.

It is a collection of DOM Elements inside a jQuery object, when you use $("li")[i] it gets a DOM Elment back thats stored inside the jQuery object, you can homewever use list[i].innerHTML to get the html without converting back to a jQuery object, just as you would with a normal Javascript selected element.

Kriggs
  • 3,731
  • 1
  • 15
  • 23