Adding classes to avoid DOM traversal

by codepo8

HTML

<header>
  <h1>Profit plans</h1>
</header>
<section id="content">
  <nav id="nav">
    <ul>
      <li><a href="#step1">Step 1: Collect Underpants</a></li>
      <li><a href="#step2">Step 2: ???</a></li>
      <li><a href="#step3">Step 3: Profit!</a></li>
    </ul>
  </nav>
  <article id="step1">
    <header><h1>Step 1: Collect Underpants</h1></header>
    <section>
      <p>
        Make sure Tweek doesn't expect anything, then steal underwear 
        and bring it to the mine.
      </p>
    </section>
    <footer><a href="#nav">back to top</a></footer>
  </article>
  <article id="step2">
    <header><h1>Step 2: ???</h1></header>
    <section>
      <p>WIP</p>
    </section>
    <footer><a href="#nav">back to top</a></footer>
  </article>
  <article id="step3">
    <header><h1>Step 3: Profit</h1></header>
    <section>
      <p>Yes, profit will come. Let's sing the underpants gnome song.</p>
    </section>
    <footer><a href="#nav">back to top</a></footer>
  </article>
</section>

CSS

* { 
    margin: 0;
    padding: 0;
  }
  footer, section, header, aside, figure {
    display: block;
  }
  body {
    padding: 2em;
    font-size: 15px;
    font-family: helvetica, arial, sans-serif;
  }

  /* move the navigation to the left */
  .js #nav {
    width: 230px;
    float: left;
  }
  .js nav a {
    display: block;
    margin: 5px 0;
    background: #ccc;
    padding: 5px 10px;
    color: #000;
  }

  /* change content to be a content panel */
  .js #content {
    position: relative;
    overflow: hidden;
    min-height: 300px;
  }


  /* push all the articles up */
  .js #content article {
    position: absolute;
    top: -700px;
    left: 250px;
  }
  /* hide 'back to top' links */
  .js article footer {
    position: absolute;
    left: -20000px;
  }

  /* keep the current article visible */
  .js #content article.current {
    top: 0;
  }

JavaScript

/* grab all the elements we need */
var nav = document.querySelector( '#nav' ),
    content = document.querySelector( '#content' ),

/* grab the first article and the first link */
    article = document.querySelector( '#content article' ),
    link = document.querySelector( '#nav a' );

/* hide everything by applying a class called 'js' to the body */
document.body.classList.add( 'js' );

/* show the current article and link */ 
article.classList.add( 'current' );
link.classList.add( 'current' );

/* event delegation for the navigation */
nav.addEventListener( 'click', function( ev ) {
  var t = ev.target;
  if ( t.tagName === 'A' ) {
    /* remove old styles */
    link.classList.remove( 'current' );
    article.classList.remove( 'current' );
    /* get the new active link and article */
    link = t;
    article = document.querySelector( link.getAttribute( 'href' ) );
    /* show them by assigning the current class */
    link.classList.add( 'current' );
    article.classList.add( 'current' );
  }
}, false);