-
Notifications
You must be signed in to change notification settings - Fork 1
Finding Parts of the Page
REFERENCE MARKUP:
<div id="example-container">
<img src="img/coded-homes-logo-sm.png" class="img-responsive" />
<img src="img/home.jpg" class="thumbnail img-responsive push-down-top" />
<section class="description">
<p class="h5">Five bedrooms, three full baths and 3,702 square feet of living space.</p>
<p>Extra-tall double-door entry opens to an inviting and spacious foyer.</p>
<p>Large gourmet kitchen with granite countertops, stainless steel appliances with double ovens. </p>
<p>The front bedroom with full bathroom just outside the door.</p>
<p>Also includes: 3 car garage, high ceilings throughout, wired for spa in backyard, dual.</p>
</section>
<h2 class="h4">Features</h2>
<ul>
<li class="feature">Luxurious sized master suite</li>
<li class="feature">Oversized walk-in closet</li>
<li class="feature">Frameless Beech cabinetry with concealed hinges</li>
<li class="feature">Elegant slab white quartz countertops with large backsplash</li>
<li class="feature">Dual china sinks with Moen faucets</li>
<li class="feature">Clear frameless shower enclosures</li>
</ul>
</div>
-
getElementsByClassName
:
getElementsByClassName
works great if you're looking for elements simply by their class name. But if your needs are a little more robust, and you want to use, say, a CSS3
selector, then querySelector
is the member you want to use. We'll look at that next. e.g.
document.getElementsByClassName('img-responsive')
-
querySelector
:
Now sometimes the elements that you want to select against the page aren't simply available through a class name or a tag name, and your needs are a little more sophisticated, this can be done using querySelector
. Now what querySelector takes in is a CSS3 selector. So before when we called getElementsByClassName, and we simply passed in the name of the class, here we can achieve the same result by passing in a selector, and in this case, it'll simply be dot (.) and then img-responsive. So what's returned from this is a single item, and this returns the first match that it finds in the document. e.g.
document.querySelector('.img-responsive')
document.querySelector('#example-container li:first-child')
-
querySelectorAll
:
Now if we want to find all matches to that selector, we can use querySelectorAll
. And notice that I'll pass in an identical selector, so .img-responsive. Now by calling querySelectorAll
, I get back once again an array of all the matches to my selector. e.g.
document.querySelectorAll('.img-responsive')
/*querySelectorAll (element)*/
var container = document.getElementById('example-container');
container.querySelectorAll('.img-responsive')
- So to make the point, let's clear this off, and let's use a selector that's a little more complicated than what we've been using so far. In this case, what I'd like to do is look at my
example-container
. - So if you notice here, there's a div that contains everything, and this is my
example-container
. I'd like to go down to the list items, and I'd like to pull out the very first list item here. - So we'll do that with this selector. So what this selector is saying is that look at the element with an Id of
example-container
. And that's delineated by the pound sign. - Then I'll say inside of that
example-container
, look for a list item, and I want to find the first child. So as I execute that, you'll notice that it returns a single item, and that matches the first item in the list. - Now notice from these brackets here, you'll see that it returned an array even though there's a single result. And that's because
querySelectorAll
always returns an array of results. And if there's no match, it simply returns an empty array, whereas by contrast,querySelector
simply returns the first matched item from your selector.
-
querySelectorAll
Returns aNodeList
:
Now in a previous example, I showed you how querySelectorAll
returns an array of elements. Now that's not exactly accurate, and I wanted to save that discussion until right now. So, for instance, if we take a look at querySelectorAll
, and we'll look at the example-container list items, you'll see that what is returned from this command is what appears to be an array of elements. But, in fact, it's not. It's actually a node list. So let's try this one more time. So here we're taking the result of querySelectorAll
and setting it to the item's variable. And now when we call toString()
against items, you can see that it returns a type of NodeList
. This is important because as you try to iterate through the return value of querySelectorAll
, it's technically not an array, and so it doesn't have the same capability and functionality that you might be used to with an array. So, for instance, you can't take a NodeList
and simply iterate over it using the foreach
function. So with that in mind, let me show you a few different ways that you can iterate through a NodeList
. e.g.
var items = document.querySelectorAll('#example-container li');
items.toString()
-
Iterating
NodeList: for
loop:
var items = document.querySelectorAll('#example-container li');
for (var i = 0, len = items.length; i < len; i++) {
console.log(items[i].innerText);
}
- **Iterating
NodeList: forEach
loop:
var forEach = Array.prototype.forEach;
var items = document.querySelectorAll('#example-container li');
forEach.call(items, function(item){
console.log(item.innerText);
});
- Live Result from
getElementsByClassName
- Now once you make a selection against an element on the page, depending on whether or now you have a live connection to it or a static connection to it will determine how it behaves as it changes throughout the lifecycle of the page.
- So, for instance, if we were to take a look at the example-container and get access to the unordered list element, and so that would be the parent element of each one of these list items, and then change the number of list items inside that unordered list, when you're working with a live result, you'll be able to recognize that change programmatically as it happens.
- So let's take a look at what this looks like. So the first thing that we'll do is set aside a selection of the unordered list itself. So here I'm using querySelector rather than querySelectorAll because I want to get the first result that matches the selector. Now there's only one unordered list inside the example-container, but I want to show you how to use both API members in different contexts.
- Next, let's select all the list items so that we can see how many we're working with as we make changes to the page. And so here, we'll change the approach a little bit and use getElementsByClassName.
var list = document.querySelector('#example-container ul');
var items = document.getElementsByClassName('feature');
console.log(items.length); //6 <- o/p
- And if you recall, each one of the list items has the class name of feature applied to it. So now let's take a look at how many items are in that result. So it returned 6 list items. Now let's add an item to the collection.
- So here I've created a new item by calling
document.createElement
, and we'll add the feature className to this item, and give it an innerText of new live feature. Out of habit, I put a parenthesis there. We want that without the parenthesis.
var newItem = document.createElement('LI');
newItem.className = 'feature';
newItem.innerText = 'new live feature';
list.appendChild(newItem);
console.log(items.length); //7 <- o/p
- So, next, we'll append that item to the list. Now watch as I press Enter, look over at the list of features, and you'll see it appear in that list. There it is. And now when I do a console.log on the items.length, you'll notice that it returns 7 even through the selection that I made for it by calling getElementsByClassName was done in advance before I'd made any changes by adding a new item to the unordered list.
- So the distinction that you want to keep in mind here is that calling getElementsByClassName will return to you a live result, whereas if you try to access even the same elements by using querySelectorAll, then you'll end up with a static result. Let's take a look at that next.
- Static Result from
querySelectorAll
- This demonstration is basically almost exactly the same as what we just did except instead of using getElementsByClassName, we'll be using querySelectorAll in order to access the items. So, first, let's get reference to the list.
var list = document.querySelector('#example-container ul');
var items = document.querySelectorAll('#example-container li');
console.log(items.length); //6 <- o/p
- Next, let's get reference to the items. And, again, here instead of calling getElementsByClassName, we'll call querySelectorAll. And in this case, since we're not going against a class name, we'll pass in a selector. And so here instead of looking for the unordered list like we are above, we'll look for the list items, and that will give us access to all the items.
var newItem = document.createElement('LI');
newItem.className = 'feature';
newItem.innerText = 'new static feature';
list.appendChild(newItem);
console.log(items.length);// 6 <- o/p
- So let's take a look at the number of items right now. So here we have 6 items in the list. Now let's add a new item to the list, and this is the same code as we had before. So as we come down, you can see that new static feature is added to the list. But when we log out the number of items, you see that it still returns 6.
- And, again, that's because querySelectorAll returns a static result, whereas getElementsByClassName returns a live result.
So this is an important distinction to keep in mind as you're building your pages. If you need to have a hook or a place where you can access elements, and you need to maintain a live result for those elements, then you'll probably want to add a class name and access them through getElementsByClassName. Otherwise, you can access any other element any way you want using querySelector or querySelectorAll using CSS3 selectors.