25. Finding Elements in the DOM

In This Chapter

  • Learn how to find elements in the DOM

  • Use the CSS selector syntax for cleverer element discovery

As we saw in the previous chapter, our DOM is nothing more than a tree-like structure (see Figure 25.1) made up of all the elements that exist in our HTML document.

Image

FIGURE 25.1

Yep. Looks like a tree-like structure all right!

That detail is only sort of important. What is important is that you have all of these HTML elements floating around that you want to access and read data from or modify. There are many ways to find these HTML elements. After all, these elements are arranged in a tree-like structure, and if there is one thing computer scientists like to do, it is figuring out crazy ways to run up and down a tree to find something.

I won’t subject you to that torture...just yet. In this chapter, you are going to learn how to use two built-in functions called querySelector and querySelectorAll to solve a good chunk of all your DOM searching needs.

Onward!

Meet the querySelector Family

To help explain the awesomeness that querySelector and querySelectorAll bring to the table, take a look at the following HTML:

<div id="main">
  <div class="pictureContainer">
    <img class="theImage" src="smiley.png" height="300" width="150" />
  </div>
  <div class="pictureContainer">
    <img class="theImage" src="tongue.png" height="300" width="150" />
  </div>
  <div class="pictureContainer">
    <img class="theImage" src="meh.png" height="300" width="150" />
  </div>
  <div class="pictureContainer">
    <img class="theImage" src="sad.png" height="300" width="150" />
  </div>
</div>

In this example, you have one div with an id of main, and then you have four div and img elements, each with a class value of pictureContainer and theImage respectively. In the next few sections, we’ll set the querySelector and querySelectorAll functions loose on this HTML and see what happens.

querySelector

The querySelector function basically works as follows:

let element = document.querySelector("CSS selector");

The querySelector function takes an argument, and this argument is a string that represents the CSS selector for the element you wish to find. What gets returned by querySelector is the first element it finds—even if other elements exist—that could get targeted by the selector. This function is pretty stubborn like that.

Taking the HTML from our earlier example, if we wanted to access the div whose id is main, you would write the following:

let element = document.querySelector("#main");

Because main is the id, the selector syntax for targeting it would be #main. Similarly, let’s specify the selector for the pictureContainer class:

let element = document.querySelector(".pictureContainer");

What gets returned is the first div whose class value is pictureContainer. The other div elements with the class value of pictureContainer will simply be ignored.

The selector syntax is not modified or made special because you are in JavaScript. The exact syntax you would use for selectors in your stylesheet or style region can be used!

querySelectorAll

The querySelectorAll function returns all elements it finds that match whatever selector you provide:

let elements = document.querySelectorAll("CSS selector");

With the exception of the number of elements returned, everything I described about querySelector above applies to querySelectorAll as well. That important detail changes how you end up actually using the querySelectorAll function. What gets returned is not a single element. Instead, what gets returned is an array-like container of elements!

Continuing to use the HTML from earlier, here is what our JavaScript would look like if we wanted to use querySelectorAll to help us display the src attribute of all the img elements that contain the class value theImage:

let images = document.querySelectorAll(".theImage");
for (let i = 0; i < images.length; i++) {
  let image = images[i];
  console.log(image.getAttribute("src"));
}

See? This is pretty straightforward. The main thing you need to do is remember how to work with Arrays, which you should be a pro at by now. The other (slightly weirder) thing is the mysterious getAttribute function. If you aren’t familiar with getAttribute and how to read values from elements, that’s totally okay. We’ll look at all that really soon. For now, just know that it allows you to read the value of any HTML attribute the HTML element in question may be sporting.

It Really Is the CSS Selector Syntax

The thing that surprised me when I first used querySelector and querySelectorAll is that it actually takes the full range of CSS selector syntax variations as its argument. You don’t have to keep it simple like I’ve shown you so far.

If you wanted to target all of the img elements without having to specify the class value, here is what our querySelectorAll call could look like:

let images = document.querySelectorAll("img");

If you wanted to target only the image whose src attribute is set to meh.png, you can do the following:

let images = document.querySelectorAll("img[src='meh.png']");

Note that I just specified an attribute selector1 as my argument to querySelectorAll. Pretty much any complex expression you can specify for a selector in your CSS document is fair game for specifying as an argument to either querySelector or querySelectorAll.

1. http://bit.ly/kirupaAttribute

There are some caveats that you should be aware of:

Not all pseudo-class selectors are allowed. A selector made up of :visited, :link, ::before, and ::after is ignored and no elements are found.

How crazy you can get with the selectors you provide depends on the browser’s CSS support. Internet Explorer 8 supports querySelector and querySelectorAll. It doesn’t support CSS3. Given that situation, using anything more recent than the selectors defined in CSS2 will not work when used with querySelector and querySelectorAll on IE8. Chances are, this doesn’t apply to you because you are probably supporting more recent versions of browsers where this IE8 issue isn’t even on the radar.

The selector you specify only applies to the descendants of the starting element you are beginning your search from. The starting element itself is not included. Not all querySelector and querySelectorAll calls need to be made from a document.

The Absolute Minimum

The querySelector and querySelectorAll functions are extremely useful in complex documents where targeting a particular element is often not straightforward. By relying on the well-established CSS selector syntax, we can cast as small or as wide a net over the elements that we want. If I want all image elements, I can just say querySelectorAll("img"). If I only want the immediate img element contained inside its parent div, I can say querySelector("div + img"). Now, that’s pretty awesome.

Before we wrap up, there is one more thing I’d like to chat with you about. Missing in all of this element-finding excitement were the getElementById, getElementsByTagName, and getElementsByClassName functions. Back in the day, these were the functions you would have used to find elements in your DOM. The querySelector and querySelectorAll functions are the present and future solutions for finding elements, so don’t worry about the getElement* functions anymore. As of right now, the only slight against the querySelector and querySelectorAll functions is performance. The getElementById function is still pretty fast, and you can see the comparison for yourself here: https://jsperf.com/getelementbyid-vs-queryselector/11.

Like a wise person once said, life is too short to spend time learning about old JavaScript functions...even if they are a bit faster!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.127.141