npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

fchui11

v1.1.2

Published

Practice finding and updating nodes in the DOM

Downloads

11

Readme

JavaScript Hide and Seek

Objectives

  1. Use document.querySelectorAll to find nested nodes
  2. Change the value of the correct DOM nodes

Introduction

In this lab, we're going to practice finding elements in the DOM. To do so, we're going to make use of two methods that are immensely useful for navigating the DOM.

If you are using the in-browser IDE, call httpserver in your IDE terminal or call open index.html if you are coding in a local environment. Use the browser as a visual aid while solving this lab. Use learn to run the tests.

querySelector()

querySelector() takes one argument, a string of selectors, and returns the first element that matches these selectors. Given a document like

<body>
  <div>
    Hello!
  </div>

  <div>
    Goodbye!
  </div>
</body>

If we called document.querySelector('div'), the method would return the first div (whose .innerHTML is "Hello!").

Selectors aren't limited to tag names, though (otherwise why not just use document.getElementsByTagName('div')[0]?). We can get very fancy.

<body>
  <div>
    <ul class="ranked-list">
      <li>1</li>
      <li>
        <div>
          <ul>
            <li>2</li>
          </ul>
        </div>
      </li>
      <li>3</li>
    </ul>
  </div>

  <div>
    <ul class="unranked-list">
      <li>6</li>
      <li>2</li>
      <li>
        <div>4</div>
      </li>
    </ul>
  </div>
  <script>
    // get <li>2</li>
    const li2 = document.querySelector('ul.ranked-list li ul li')

    // get <div>4</div>
    const div4 = document.querySelector('ul.unranked-list li div')
  </script>
</body>

In the above example, the first query says, "Starting from document (the object we've called querySelector() on), find a ul with a className of ranked-list (the . is for className). Then find an li that is a child of that ul. Then find a ul that is a child (but not necessarily a direct descendant) of that li. Finally, find an li that is a child of that (second) ul."

NOTE: The HTML property class is referred to as className in JavaScript. It's... unfortunate.

What, then, does the second call to querySelector() say? Puzzle it out for a bit, and then read on.

Puzzle a bit longer!

Just a bit longer!

Okay, the second call says, "Starting from document, find a ul with a className of unranked-list. Then find an li descended from ul.unranked-list and a div descended from that li."

Interlude: Selectors

Now is probably a good time to read up on selectors. They're super important and relatively straightforward to pick up. Play around on the MDN page while you're getting the hang of it! Then come back when you're ready.

querySelectorAll()

querySelectorAll works a lot like querySelector() -- it accepts a selector as its argument, and it searches starting from the element that it's called on (or from document) -- but instead of returning the first match, it returns a NodeList (which, remember, is not an Array) of matching elements.

Given a document like

<main id="app">
  <ul class="ranked-list">
    <li>1</li>
    <li>2</li>
  </ul>

  <ul class="ranked-list">
    <li>10</li>
    <li>11</li>
  </ul>
</main>

If we called document.getElementById('app').querySelectorAll('ul.ranked-list li'), we'd get back a NodeList of <li>1</li>, <li>2</li>, <li>10</li>, <li>11</li>.

We could change the .innerHTML of these lis like so:

const lis = document
  .getElementById('app')
  .querySelectorAll('ul.ranked-list li');

for (let i = 0; i < lis.length; i++) {
  lis[i].innerHTML = (i + 1).toString();
}

Now our lis, even though they're children of two separate uls, will count up from 1 to 4.

Using this loop construct, we could even, say, call querySelector() or querySelectorAll() on these children to look deeper and deeper into a nested structure... (hint!).

Instructions

Instructions for In-Browser Learn IDE Users

If you are using the Learn IDE available in your browser, you will automatically clone down the files you need when you click 'Open IDE', but in order to view index.html, you will need to use httpserver to serve the HTML page temporarily. In the terminal, type httpserver and press enter. You will see that Your server is running at ... followed by a string of numbers and dots. This string is a temporary IP address that is hosting your index.html file. Copy this string of numbers, open a new tab and past the string in to the URL bar.

Instructions for Students Using an Stand Alone Text-Editor

If you are using an standalone text editor such as Sublime or Atom, before we get started, follow these instructions to manually fork and clone the lesson repository on GitHub. In your forked and cloned copy, you'll find the index.html file, which you can then manually open up in the browser. (For instructions on opening HTML files in the browser from the Learn IDE, see this Help Center article.)

In index.html, you'll see that we've set up a basic document for you. We'll be testing against this document, but you should still write your code in index.js. We'll handle loading everything up for you.

  • Define a function getFirstSelector(selector), which accepts a selector and returns the first element that matches.
  • Define a function nestedTarget() that pulls a .target out of #nested (# is used for IDs in selectors — but you knew that because you read the docs, right? :) ). (Note that in index.html #nested and .target just happen to be divs. This method should work with arbitrary elements.)
  • Define a function increaseRankBy(n) that increases the ranks in all of the .ranked-lists by n. (You might need to make use of parseInt()
  • Define a function deepestChild() that pulls out the most deeply nested child element from div#grand-node. (Remember, you can iterate over elements and call querySelector() and querySelectorAll() on them. This is challenging to implement correctly, but not beyond your ability!)

HINT 1: Your solution for deepestChild() does not need to be totally generic; we don't expect it to work in every case. For example, we know that div#grand-node has only one node at each level — for this lab, you can solve for that case, and not worry about a case where there are sibling nodes.

HINT: Remember learning about breadth-first search? A similar technique might come in handy here.

Have fun, and good luck!

Resources