Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript JavaScript and the DOM (Retiring) Getting a Handle on the DOM Practice Selecting Elements

Jesse Billard
Jesse Billard
3,268 Points

JS and DOM - Stuck on selecting certain HTML elements, but not others.

Just trying to select a 'nav' list and set it to a variable. It's the first and only 'nav' in the HTML, so i used document.querySelector('nav')....but no dice. Help por favor!

js/app.js
let navigationLinks = document.querySelector('nav')
let galleryLinks;
let footerImages;
index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Nick Pettit | Designer</title>
    <link rel="stylesheet" href="css/normalize.css">
    <link href='http://fonts.googleapis.com/css?family=Changa+One|Open+Sans:400italic,700italic,400,700,800' rel='stylesheet' type='text/css'>
    <link rel="stylesheet" href="css/main.css">
    <link rel="stylesheet" href="css/responsive.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
  </head>
  <body>
    <header>
      <a href="index.html" id="logo">
        <h1>Nick Pettit</h1>
        <h2>Designer</h2>
      </a>
      <nav>
        <ul>
          <li><a href="index.html" class="selected">Portfolio</a></li>
          <li><a href="about.html">About</a></li>
          <li><a href="contact.html">Contact</a></li>
        </ul>
      </nav>
    </header>
    <div id="wrapper">
      <section>
        <ul id="gallery">
          <li>
            <a href="img/numbers-01.jpg">
              <img src="img/numbers-01.jpg" alt="">
              <p>Experimentation with color and texture.</p>
            </a>
          </li>
          <li>
            <a href="img/numbers-02.jpg">
              <img src="img/numbers-02.jpg" alt="">
              <p>Playing with blending modes in Photoshop.</p>
            </a>
          </li>
        </ul>
      </section>
      <footer>
        <a href="http://twitter.com/nickrp"><img src="img/twitter-wrap.png" alt="Twitter Logo" class="social-icon"></a>
        <a href="http://facebook.com/nickpettit"><img src="img/facebook-wrap.png" alt="Facebook Logo" class="social-icon"></a>
        <p>&copy; 2016 Nick Pettit.</p>
      </footer>
    </div>
  <script src="js/app.js"></script>
  </body>
</html>

7 Answers

I Dilate
I Dilate
3,983 Points

Hey Jesse,

No problem.

There are several ways to select specific items in the list.

Of course, one way is always to add a class to the elements you want - but in many cases you aren't able to do that, for example when a list is hundreds or thousands of items long, or if it's dynamically generated for the page.

So it's a good idea to know how to do it from JavaScript.

In fact, there are two possible solutions...

document.querySelectorAll(); returns a collection of elements (in an array), so you can select specific items in the way you described in your message. So for example:

let myNav = document.querySelectorAll('nav a');
let firstNav = myNav[0];

firstNav will return the first item in the array (the first link).

Alternatively, you can use a CSS selector. You can put any standard CSS selector into your querySelector / querySelectorAll (brackets)!

Did you checkout the lesson that talks about using nth-child()?

For example:

let secondNav = document.querySelector('nav li:nth-child(2) a')

secondNav will return the second link on the list (note I'm using querySelector, rather than querySelectorAll, which returns a single node rather than a node list).

Using nth-child and nth-of-type can be a bit difficult to get your head around though. If you're interested in them, other than the lesson in this course that covers them very briefly, I'd suggest reading up here: nth-child at w3schools and here - nth-of-type at w3schools. Lastly, these nth-child recipes can be really useful too!

Jesse Billard
Jesse Billard
3,268 Points

Thanks so much for the generous breadth of your responses Rich! I totally forgot about nth-child...i can imagine it being very useful for future selections. The links provided great insights as well. Take care!

Vladimir Plokhotniuk
Vladimir Plokhotniuk
5,464 Points

Hi. Help me pls. Why then doesn't working second step?: let galleryLinks = document.querySelectorAll("gallery a");

Scott Junner
Scott Junner
9,010 Points

If you only select using 'nav' you don't actually return a list. You need to get deeper.

Try something like

let navigationElement = document.querySelector('nav');
let list = navigationElement.querySelectorAll('li');

By the way you can always use

console.log(thing_you_want_to_examine);

to help you.

Jesse Billard
Jesse Billard
3,268 Points

Thanks Scott, I'll try this direction

Scott Junner
Scott Junner
9,010 Points

To be clear. document.querySelector('nav') does NOT return a list. It returns a single nav object which includes everything withing the <nav> tag. If you tried document.querySelector('ul') you still wouldn't get a list. You'd get a single ul object which includes everything within the <ul> tag. And to really rub it in, even if you tried document.querySelector('li') you still wouldn't get a list. You'd get the first li object the querySelector() method stumbled across.

That's why you have to traverse deeper into the nav object AND use querySelectorAll('li') so you get ALL of the <li> elements. Then you will have a list.

I Dilate
I Dilate
3,983 Points

When you say "no dice" - what exactly is happening? What were you trying to select, the <nav> or ultimately to do something with the list items (as per Scott's answer)?

If you do console.log(navigationLinks); is it returning anything at all?

Any errors in your JS Console?

Jesse Billard
Jesse Billard
3,268 Points

When I submit to the challenge: let navigationLinks = document.querySelector('nav')

it responds with 'expected 3 links not undefined'

but when I console.log(navigationLinks)

I don't get any errors and see a node list with the children of the nav section.

This is one hell of a jump from the amount of instruction we have been given in this nav selection to the answer we are expected to come up with. I along with everyone else short of Tim Berners-Lee of course had the same issue. Thanks for the question. I would thank the instructor for the answer but he is part of the group that created this poorly designed situation. Miochael T. Slattery

I Dilate
I Dilate
3,983 Points

I disagree - everything you need to answer this challenge has been covered in the lesson.

My advice is to take some notes as you progress, pausing the video if you need to. I have a notebook where I can lookup what I wrote about querySelector() during the video - it has a line next to it that says "selects just one element - the first of that type"... which would have got me 9/10ths of the way to answering the challenge.

You can Google what querySelector() does very easily too.

Really, you don't need to be Tim Berners-Lee... nice guy though he is.

I Dilate
I Dilate
3,983 Points

Hey Jesse,

That's right.

Do you remember from the lessons the difference between querySelector() and querySelectorAll()?

  • querySelectorAll() will return a list of elements - good for selecting multiple elements.
  • querySelector() will return just a single element - the first of whatever you're searching for - good for selecting a unique element.

Let's review the question:

In the app.js file on line 1, select all links in the nav element and assign them to navigationLinks.

So it's asking for more than 1 item - so let's go for querySelectorAll() instead.

Furthermore, you're passing in just 'nav' - which will select only the <nav> element. But it's asking for all the links (<a> tags) contained within the <nav>.

So do you remember how to select a descendant of an element?

Within querySelectorAll() you can simply list them one after the other to indicate that the later is contained within the former - 'nav a' in this case will give us the links inside the nav.

So, in short, this is what you're looking for:

let navigationLinks = document.querySelectorAll('nav a');

Does that make more sense now?

Good luck with the rest of the lesson :-) Rich

Jesse Billard
Jesse Billard
3,268 Points

Thanks so much for the help Rich! Before reading your comment, I was honing in on it, but still was off. I was trying:

document.querySelectorAll('nav li')

but to no avail...I thought it would work because the <a>'s are contained within the <li> tags...but it was getting late Friday, I was pizza deprived and couldn't see the simple change I needed to make.

Let's say for example. I wanted to select only the first and second <a> in that <nav> list. I suppose one way to do it, would be to give them a class name, then use document.getElementsByClassName...but would something like this work as well...?

document.querySelectorAll('nav a')[0, 1] ??

Vladimir Plokhotniuk
Vladimir Plokhotniuk
5,464 Points

document.querySelectorAll('gallery a'); ...Why does the code choose 2 links, not 3 ?

The question is clearly beyond the scope of the instruction given. ( I am thinking of a number between 1 & 100....can you guess it?

If it is a fair question why are you reamending the answer given?