Lesson Tuesday

Popping up dialogue boxes isn't very interesting, so let's move on to actually manipulating our web page by showing and hiding elements. Here's the HTML for the page we'll work on:

peek-a-boo.html
<!DOCTYPE html>
<html>
  <head>
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css">
    <link href="css/styles.css" rel="stylesheet" type="text/css">
    <script src="js/jquery-1.12.0.js"></script>
    <script src="js/scripts.js"></script>
    <title>Peek-a-boo</title>
  </head>
  <body>
    <div class="container">
      <h1>Peek-a-boo</h1>

      <p>Let's play peek-a-boo. Click here to see the surprise!</p>

      <img src="img/walrus.jpg">
    </div>
  </body>
</html>

Make sure that you have downloaded and correctly linked bootstrap and jquery. You will need these for pretty much every project.

Obviously, this doesn't work yet. The first thing we should do is to hide the walrus with a bit of CSS. As usual, we'll make a file called styles.css in our css folder. Then, we'll add a CSS rule to hide the image:

css/styles.css
img {
  display: none;
}

Now, we can use jQuery to show the walrus when you click the paragraph above it:

js/scripts.js
$(document).ready(function() {
  $("p").click(function() {
    $("img").show();
  });
});

Very nice! Here, we've used another jQuery function called .show() that will, obviously, show a hidden element.

But wouldn't it be nicer if the text of the paragraph changed, so after you clicked it, it said "What a cute walrus! Click here to hide her again." Let's do that now. First, we need to make a couple changes to our HTML:

peek-a-boo.html
<body>
  <div class="container">
    <h1>Peek-a-boo</h1>

    <div class="walrus-hidden">
      <p>Let's play peek-a-boo. Click here to see the surprise!</p>
    </div>

    <div class="walrus-showing">
      <p>What a cute walrus! Click here to hide her again.</p>
      <img src="img/walrus.jpg">
    </div>
  </div>
</body>

Now we've wrapped our page in two <div>s: one for when the walrus is hidden, and one for when she's showing. Let's update our CSS to hide the walrus at first:

css/styles.css
.walrus-showing {
  display: none;
}

And now, we'll update our JavaScript:

js/scripts.js
$(document).ready(function() {
  $("p").click(function() {
    $(".walrus-showing").show();
    $(".walrus-hidden").hide();
  });
});

One of the cool things about jQuery is that it uses the exact same selectors as CSS.

Now, our code successfully changes the text that is shown above the walrus! Of course, it doesn't switch back and hide her again, so let's update our code once more to take care of that:

js/scripts.js
$(document).ready(function() {
  $("p").click(function() {
    $(".walrus-showing").toggle();
    $(".walrus-hidden").toggle();
  });
});

Nice. Now everything works as planned.

There's something I don't like about this page, though. Most users expect that when an element is clickable, it's a different color, and that when they hover their mouse over it, the cursor will change to a hand and the text will be underlined. Fortunately, this is easy to implement with CSS:

css/styles.css
p {
  cursor: pointer;
  color: #0088cc;
}

p:hover {
  text-decoration: underline;
}

Now, this works, and it looks much better. But I'm still not satisfied. Here's why. Let's add another paragraph to this page:

peek-a-boo.html
<body>
  <div class="container">
    <h1>Peek-a-boo</h1>
    <p><strong>Peek-a-boo</strong> is an ancient game riddled in mystery and deceit. Though it appears to be an innocent children's pastime, you may change your mind when you learn of its treacherous history.</p>

    <div class="walrus-hidden">
      <p>Let's play peek-a-boo. Click here to see the surprise!</p>
    </div>

    <div class="walrus-showing">
      <p>What a cute walrus! Click here to hide her again.</p>
      <img src="img/walrus.jpg">
    </div>
  </div>
</body>

Gross! Our styling has run amok and is applied to the intro paragraph, which really shouldn't be clickable. And even worse: if you click it, it toggles the walrus! We really need to limit the scope of our CSS and JavaScript. Let's add some <span> tags to clean this up:

peek-a-boo.html
<body>
  <div class="container">
    <h1>Peek-a-boo</h1>
      <p><strong>Peek-a-boo</strong> is an ancient game riddled in mystery and deceit. Though it appears to be an innocent childrens' pastime, you may change your mind when you learn of its treacherous history.</p>

    <div class="walrus-hidden">
      <p>Let's play peek-a-boo. <span class="clickable">Click here</span> to see the surprise!</p>
    </div>

    <div class="walrus-showing">
      <p>What a cute walrus! <span class="clickable">Click here</span> to hide her again.</p>
      <img src="img/walrus.jpg">
    </div>
  </div>
</body>

Now, we can update our CSS:

css/styles.css
.walrus-showing {
  display: none;
}

.clickable {
  cursor: pointer;
  color: #0088cc;
}

.clickable:hover {
  text-decoration: underline;
}

And JavaScript:

js/scripts.js
$(document).ready(function() {
  $(".clickable").click(function() {
    $(".walrus-showing").toggle();
    $(".walrus-hidden").toggle();
  });
});

Ah, that's much better now. When you're writing JavaScript (and CSS), it's a good idea to use classes to be specific about the elements you want to select. But keep in mind, if you have more than one thing on the page that can change, you might want to use one class for your CSS and another class for of each of the actions. For example, if your page had one place that let you show and hide a walrus, and another place that let you show and hide an emu, you might have both clickable <span>s styled with the clickable class, but one <span> with the toggle-walrus, and the other with a toggle-emu class.

Speaking of being specific, it feels wrong to me to use the classes walrus-hidden and walrus-showing. We're supposed to use classes to identify similar parts of our pages that should look and act the same. For our clickable span, using a class makes perfect sense: we have two places on the page where we use it, and I can imagine that our website could potentially use it in many, many more places. But walrus-hidden and walrus-showing really couldn't be re-used anywhere else on this page - these sections should be unique. Often, this is the case with JavaScript: we want to identify a unique part of the page that should be changed when a unique event happens. For this case, we can use an id. Check it out:

peek-a-boo.html
<body>
  <div class="container">
    <h1>Peek-a-boo</h1>
      <p><strong>Peek-a-boo</strong> is an ancient game riddled in mystery and deceit. Though it appears to be an innocent children's pastime, you may change your mind when you learn of its treacherous history.</p>

    <div id="walrus-hidden">
      <p>Let's play peek-a-boo. <span class="clickable">Click here</span> to see the surprise!</p>
    </div>

    <div id="walrus-showing">
      <p>What a cute walrus! <span class="clickable">Click here</span> to hide her again.</p>
      <img src="img/walrus.jpg">
    </div>
  </div>
</body>

Now, we change our CSS like this:

css/styles.css
#walrus-showing {
  display: none;
}

And our JavaScript like this:

js/scripts.js
$(document).ready(function() {
  $(".clickable").click(function() {
    $("#walrus-showing").toggle();
    $("#walrus-hidden").toggle();
  });
});

So, what's the difference between a class and an ID, except that we use a . to select a class and a # to select an ID? Nothing, really, except that you can only use an ID once on a page, and you can use a class as many times as you want. But by using an ID, you can be clear that you're referring to one particular thing, rather than potentially referring to several.

We could actually go one step further in thinking about how to make our code re-usable. Instead of calling the IDs walrus-showing and walrus-hidden, we could call them initially-hidden and initially-showing. That way, we could re-use this code on other pages that have the same kind of toggling functionality.

Now, a quick lecture before you move on to practicing all that you've just learned. When we use JavaScript to manipulate the page, we haven't changed the source code. No matter how much we change the page with JavaScript, if you hit the Refresh button in your browser, it will go back to the initial state. What JavaScript is doing is manipulating the Document Object Model, or DOM. The DOM is your browser's interpretation of the HTML it reads. If you inspect an element of the page, you're actually seeing the DOM, not the HTML. Try inspecting the page we've been working on, and then click the click here part that changes the page. You can see in the inspector that the DOM changes.

If you'd like to do some further reading about what the DOM actually is, check out this article by Chris Cormier from CSS tricks.

Now, try these concepts out on your own pages. Add JavaScript to hide and show various elements. Use id's and classes to keep things neat and tidy. Additionally, here are a few other jQuery methods to try out:

  • fadeIn()
  • fadeOut()
  • fadeToggle()
  • slideDown()
  • slideUp()
  • slideToggle()

Play around with them to get practice using these simple jQuery effects!

Terminology


  • The Document Object Model, or DOM, is your browser's interpretation of the HTML it reads. When JavaScript changes the page, it updates the DOM, not the HTML.

Tips


  • Use classes (e.g. .my-class) for things that are on the page multiple times. Use IDs (e.g. #my-id) for something that is unique on the page.

Examples


Show, hide, and toggle elements:

$(".my-class").show();
$(".my-class").hide();
$(".my-class").toggle();

Make a class look like a link:

.clickable {
  cursor: pointer;
  color: #0088cc;
}

.clickable:hover {
  text-decoration: underline;
}