Simple interactivity with jQuery

Today we're going to learn how to add simple interactivity to our web pages. To do this, we're going to learn a tiny amount of Javascript. Don't get intimidated, though! The examples we're going to look at are very simple, but are also very powerful.

Javascript is a programming language. You can include bits of Javascript in your HTML code that allow you to make changes to the way the document is structured, and to styles associated with elements, in response to certain events.

We'll be using a Javascript library called jQuery in the examples below. (jQuery makes Javascript easier to write, especially for the kinds of simple cases that we'll be talking about in this section.) See the "Conclusion" section for more information and further reading about both Javascript and jQuery.

Because we're not going to have time to go into Javascript/jQuery programming in great detail, try to think of the examples in this section as being a kind of mad lib---you should leave most of the code alone, and I'll try to carefully specify which parts you can change, and how such changes will affect what happens on the page.

Making things happen with clicks

In order to use jQuery, we need to put the following line in the <head> element of our web page:

<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>

This is a special tag that grabs some Javascript code from another URL and puts it into your page.

Once that tag is in your page, you can now put jQuery code on your page inside of <script> tags, like this:

<script type="text/javascript">
$(function() {
    // your code here
});
</script>

You can put this <script> tag wherever you like, though you might prefer putting it either in your <head> tag or near the bottom of your document. Consider the above bit of code to be boilerplate. The only part you'll be changing is the line where it says // your code here.

Clicking <button>s

If we're going to make our page interactive, we need to give the user something to interact with. We'll talk about making <a> tags do something other than linking to other pages in a second, but first let's discuss the HTML <button> tag. On its own, the <button> tag doesn't do anything interesting---it just sits there on the page, looking like a button. You can click it, but it doesn't do anything:

<button>This is a button.</button>

In order to make the button do something other than sit there, we have to give it a behavior with jQuery. Here's what that looks like:

<button class="clickme">Click Me!</button>
<script type="text/javascript">
    $(function() {
        $(".clickme").on("click", function() {
            alert("Good job!");
        });
    });
</script>

Click the button and see what happens. (You should see a little window pop up that says "Good job!")

But whoa, that's a lot of stuff! A lot of strange parentheses and quotes and brackets and who knows what else. Here's the code from inside the <script> tag again---this time with the lines numbered and the "movable" parts (i.e., you can swap out) highlighted in bold.

1 $(function() {
2   $(".clickme").on("click", function() {
3     alert("Good job!");
4   });
5 });

Notes:

EXERCISE: Change the class name of the button in the above example, then change the jQuery code so that it still causes the alert window to appear when the button is clicked.

Hiding elements

So we're well on our way to making our pages interactive. But making a little dialog window appear doesn't seem very useful. Preferably we'd like to make it so user action results in some kind of change happening on the page itself.

Well, it so happens that this is easy to do! The first thing we're going to learn how to do is to reveal and hide elements in response to the user clicking a button. In the following example, the paragraph tag will disappear when the user clicks the button.

<p class="hideme">This paragraph is not safe for work.</p>
<button class="hideparagraph">Hide your shame!</button>
<script type="text/javascript">
    $(function() {
        $(".hideparagraph").on("click", function() {
            $(".hideme").hide();
        });
    });
</script>

This paragraph is not safe for work.

This example is very much like the previous example: we're creating an event handler, this time on elements of class .hideparagraph. The thing that's different this time is the code inside the event handler: what we want the browser to do when the button is clicked. The new code is this:

  $(".hideme").hide();

This line tells jQuery to find all elements on the page with the hideme class and... hide them. (Behind the scenes, jQuery "hides" the elements by setting their display properties to none.) If you wanted the event to hide elements belonging to a different class, you could change the string hideme to something else.

The string hide has no inherent meaning; it's just one of the many special words that jQuery understands. You would only know that hide does what it does if you'd read its documentation. Learning jQuery is all about learning all of the different things we can put where the word hide is in this example, and what those things do. (The full list is here, but you might be most interested in jQuery effects.)

Revealing elements

What's good for the goose is good for the gander, and likewise it's possible to reveal previously hidden elements, using code very similar to the example above. Here's how:

<p>Q: Why didn't the skeleton cross the road?</p>
<p class="punchline" style="display: none;">A: Because it didn't have the
    guts.</p>
<button class="telljoke">Tell the joke!</button>
<script type="text/javascript">
    $(function() {
        $(".telljoke").on("click", function() {
            $(".punchline").show();
        });
    });
</script>

Q: Why didn't the skeleton cross the road?

In the example above, we need to set the element's display to none initially, so it's hidden when the page is loaded. We then set up an event handler that asks the browser to perform the following task when the user clicks on an element with the .telljoke class:

  $(".telljoke").show()

This time, we're using jQuery's show function, which causes all elements belonging to the class in the parentheses before it to be displayed (if they weren't already displayed).

(Joke sourced from the Internet.)

Adding new styles with .addClass()

Showing and hiding elements isn't all we can do! We can also use jQuery to change the CSS style of elements in more sophisticated ways. In particular, jQuery's .addClass() function allows us to "add" a class to an element. When the new class is added, the element will have whatever pre-defined styles exist for that class. Here's an example:

<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<style type="text/css">
    .flashy { color: green; font-family: fantasy; font-size: 150%; }
</style>
<p class="hello">Hello, dear friends.</p>
<button class="fancymaker">Make me fancy!</button>
<script type="text/javascript">
    $(function() {
        $('.fancymaker').on('click', function() {
            $('.hello').addClass('flashy');
        });
    });
</script>

Hello, dear friends.

There are a few interesting things going on here. First of all, you'll notice that the <p> tag has a class of hello, but that class doesn't have any styles associated with it! Weird. But this is a common strategy when you're marking up HTML for interactivity: the class hello is there just so we have something to "find" the element with in the event handler.

Secondly, the .addClass() function works like this:

  $('.hello').addClass('flashy');

Unlike the .hide() and .show() functions, the .addClass() function needs you to put something between the parentheses---namely, the name of the class you want to add to the element.

You can replace .hello with whichever class you want---all elements that have that class will be acted upon. You can also replace flashy with whatever you want. The class flashy (or whatever you change it to) will be added to those elements. They'll have whatever styles they previously had, plus whatever styles you've specified for .flashy in the style sheet. (Don't forget the quotation marks here---they're important!)

EXERCISE: Investigate the .removeClass() function. Add another button to the above example to remove the fancy class from elements with class hello.

Toggling

It's often useful to have a way to say the following: "If an element is visible, then hide it; but if it's hidden, show it." Or: "If an element doesn't belong to a particular class, add the class; if it does belong to that class, then remove the class." Sort of like a light switch. Ordinarily, learning how to implement this kind of functionality would involve my teaching you all manner of strange things like variables and booleans and if statements. But jQuery makes it easy, with the following two functions.

The first is .toggle(), which displays an element if it's hidden, and hides it if it's visible:

<p>I find this example incredibly <span class="un">un</span>interesting.</p>
<button class="change">Change the sentence!</button>
<script type="text/javascript">
    $(function() {
        $(".change").on("click", function() {
            $(".un").toggle();
        });
    });
</script>

I find this example incredibly uninteresting.

The first time you click the "Change the sentence!" button, the un span disappears. But if you click it again, the un span comes back!

There's another function, .toggleClass(), which works like .toggle(), except that it toggles a class. For example:

<style type="text/css">
    .shadow { text-shadow: 2px 2px 3px grey; }
</style>
<p class="proverb">Worry gives a small thing a big shadow.</p>
<button class="demonstrate">Demonstrate!</button>
<script type="text/javascript">
    $(function() {
        $(".demonstrate").on("click", function() {
            $(".proverb").toggleClass("shadow");
        });
    });
</script>

Worry gives a small thing a big shadow.

If you've figured out how to use .addClass() and how to use .toggle(), figuring out how .toggleClass() works should be easy. In the example above, clicking the button adds the .shadow class to the <p> tag with class proverb. Clicking the button again removes the .shadow class.

Clicking other things and preventing defaults

Buttons are nice, but what if we wanted to make click event handlers for other kinds of elements? Well, it's possible!

<img src="bigriker.jpg" class="riker">
<p>Click Big Will to get a Riker quote!</p>
<p class="rikerquote" style="display: none;">Even Klingons need love now
and then.</p>
<script type="text/javascript">
    $(function() {
        $(".riker").on("click", function() {
            $(".rikerquote").show();
        });
    });
</script>

Click Big Will to get a Riker quote!

You can attach event handlers to pretty much any element. A special case, however, is <a> tags. Here's an example to demonstrate:

<p>Let the story <a href="#" class="continue">continue</a>.</p>
<p class="continuation" style="display: none;">Here is the continuation of
the story.</p>
<script type="text/javascript">
    $(function() {
        $(".continue").on("click", function() {
            $(".continuation").show();
        });
    });
</script>

Let the story continue.

I have to put an href attribute on the <a> tag to make it show up as a link. But when I click on the link, it... does what a link does, and the browser attempts to load a new page (even if I've left the href attribute blank). If you look very closely, you can see that the text in the continuation class does appear, very briefly, before the page reloads. What we'd like to do is have the link behave like a link, but to have it stop short of actually making the browser load the new page. We can do this by subtly changing the above example to this:

<p>Let the story <a href="#" class="continue2">continue</a>.</p>
<p class="continuation2" style="display: none;">Here is the continuation of
the story.</p>
<script type="text/javascript">
    $(function() {
        $(".continue2").on("click", function(e) {
            $(".continuation2").show();
            e.preventDefault();
        });
    });
</script>

Let the story continue.

There are two changes we made in this example. Here's the new code for the event handler:

$(".continue2").on("click", function(e) {
  $(".continuation2").show();
  e.preventDefault();
});

First of all, we put a little e between the parentheses on the first line. Secondly, put e.preventDefault(); at the end of the list of things we want to happen when the event happens. I'm not going to go into detail about what these changes mean! I'll just leave it at this: you need to do those two things to your event handler if you want an <a> tag to NOT cause a new page to load.

Changing an element's contents

Changing styles is all well and good, and so is making elements appear and disappear. But we can also use jQuery to change the content of the page itself! There are two functions for doing this. The first is .text(), which modifies the contents of an element. Here's an example:

<p>It was the <span class="twocities">best</span> of times.</p>
<button class="bestworst">Change!</button>
<script type="text/javascript">
    $(function() {
        $('.bestworst').on('click', function() {
            $('.twocities').text("worst");
        });
    });
</script>

It was the best of times.

The code above uses the .text() function to change the content of the <span> tag with class twocities. Pretty slick. Of course, we can change more than just individual words:

<p class="frontier">Space: the final frontier.</p>
<button class="voyages">Please continue, Captain.</button>
<script type="text/javascript">
    $(function() {
        $('.voyages').on('click', function() {
            $('.frontier').text("These are the voyages of the starship Enterprise.");
        });
    });
</script>

Space: the final frontier.

You can put whatever you want between the quotation marks in the .text() function, but the text all has to be on the same line.

But there are some "special characters" that you can't directly include between the quotation marks---in particular, you can't use the " quotation mark itself. (If you do, the browser thinks you're done writing your text, and then interprets the rest of what's written on the line as garbage.) To get around this: whenever you want to include a " in your text, replace it with \". For example:

<p class="tomato">You say "tomayto."</p>
<button class="next">But...</button>
<script type="text/javascript">
    $(function() {
        $('.next').on('click', function() {
            $('.tomato').text("I say \"tomahto.\"");
        });
    });
</script>

You say "tomayto."

The .text() function allows us to change text, but it doesn't allow us to add new HTML to the document. If we attempt to do so, a strange thing happens:

<p class="rikerparagraph">I am become Riker, destroyer of worlds.</p>
<button class="rikeractivate">Appear!</button>
<script type="text/javascript">
    $(function() {
        $('.rikeractivate').on('click', function() {
            $('.rikerparagraph').text("<img src=\"bigriker.jpg\">");
        });
    });
</script>

I am become Riker, destroyer of worlds.

The browser puts the "actual" text into the page, instead of adding the element described. This can be useful in some circumstances, but sometimes we actually want to add new HTML to the page. We can do this with the .html() function:

<p class="rikerparagraph2">I am become Riker, destroyer of worlds.</p>
<button class="rikeractivate2">Appear!</button>
<script type="text/javascript">
    $(function() {
        $('.rikeractivate2').on('click', function() {
            $('.rikerparagraph2').html("<img src=\"bigriker.jpg\">");
        });
    });
</script>

I am become Riker, destroyer of worlds.

Nice! The only change in this example from the previous one is that I used .html() instead of .text(). (Notice how I needed to use \" to include actual quotes inside of both examples, though.)

(Unfortunately, jQuery doesn't include a function like .toggleText() that works similarly to .toggle() and .toggleClass(). This thread has some reasonable workarounds, however!)

Two things at once!

So far, all of the examples we've looked at just do one thing in response to user action: if the user clicks something, one thing happens afterwards. But we can actually include multiple actions in the same event handler. They just need to be on separate lines. Here's an example, making Riker dance:

<style type="text/css">
    .rikerhigh { position: relative; top: -50px; }
    .rikerlow { position: relative; top: 50px; ]
</style>
<p>
    <img src="bigriker.jpg" class="riker1">
    <img src="bigriker.jpg" class="riker2">
    <img src="bigriker.jpg" class="riker3">
</p>
<button class="dance">Dance!</button>
<script type="text/javascript">
    $(function() {
        $('.dance').on('click', function() {
            $('.riker1').toggleClass('rikerhigh');
            $('.riker2').toggleClass('rikerlow');
            $('.riker3').toggleClass('rikerhigh');
        });
    });
</script>

In the example above, clicking the button causes three things to happen: .toggleClass() is called for three different elements.

Basic JQuery effects

The .show(), .hide() and .toggle() functions are great, but they're visually a little uninteresting. To add a bit of flare, jQuery offers a number of other functions that cause elements to "fade" or "slide" in and out.

The .fadeIn(), .fadeOut(), and .fadeToggle() functions work exactly like .show(), .hide() and .toggle(), except they apply a "fading" animation when doing their work. Here's an example:

<p>
    <img src="bigriker.jpg" class="rikerfade">
</p>
<button class="fadeout">Fade out!</button>
<button class="fadein">Fade in!</button>
<button class="fadetoggle">Fade toggle!</button>
<script type="text/javascript">
    $(function() {
        $('.fadeout').on('click', function() {
            $('.rikerfade').fadeOut();
        });
        $('.fadein').on('click', function() {
            $('.rikerfade').fadeIn();
        });
        $('.fadetoggle').on('click', function() {
            $('.rikerfade').fadeToggle();
        });
    });
</script>

The .slideUp(), .slideDown(), and .slideToggle() functions work similarly, but apply a "sliding" animation:

<p>
    <img src="bigriker.jpg" class="rikerslide">
</p>
<button class="slideup">Slide up!</button>
<button class="slidedown">Slide down!</button>
<button class="slidetoggle">Slide toggle!</button>
<script type="text/javascript">
    $(function() {
        $('.slideup').on('click', function() {
            $('.rikerslide').slideUp();
        });
        $('.slidedown').on('click', function() {
            $('.rikerslide').slideDown();
        });
        $('.slidetoggle').on('click', function() {
            $('.rikerslide').slideToggle();
        });
    });
</script>

Opening and closing windows

The last thing we'll talk about here is how to use Javascript to open new windows. There's a function called window.open() that you can put inside of your event handlers to cause a new window to appear on the screen. Here's a simple example:

<button class="sesame">Open!</button>
<script type="text/javascript">
    $(function() {
        $(".sesame").on("click", function() {
            window.open("opened.html");
        });
    });
</script>

This example opens a new browser window with opened.html as its URL. Simple enough! But sometimes we want to be able to control the position and dimensions of the window that we open. For this, we can pass extra "parameters" to the window.open() function. ("Parameters" in this case are more bits of code that go inside the parentheses, separated by commas.) Here's some example code that you can use as a template:

<button class="windowopen1">Click here to open a new window.</button>
<script type="text/javascript">
    $(function() {
        $(".windowopen1").on("click", function(e) {
            window.open("opened.html", "_blank",
                "left=100,top=100,width=300,height=600");
        });
    });
</script>

Be careful with the above example---there are quotation marks in weird places, and you need to just kind of leave them all where they are. The parts you can change are in bold below:

$(".windowopen1").on("click", function(e) {
    window.open("opened.html", "_blank",
        "left=100,top=100,width=300,height=600");
});

The values next to left and top control how many pixels from the upper left-hand corner of the window should appear. The values next to width and height control the size of the new windows (again, in pixels).

If you want to include a link in a web page that closes the current window, you can include the following code. (Note: Be careful! If you click on the link on this page, it will close this window!)

<a href="javascript:window.close()">Close this window.</a>

Close this window.

EXERCISE: Combine one of the e.preventDefault() examples with one of the window-opening examples above to make a web page where clicking on a link causes a new window to open.

Conclusion

Hey, you did a great job! Now you have the tools to make interesting and sophisticated web pages, all from scratch. You are a powerful person with an impressive level of mastery over technology! If you're interested in learning more about jQuery and Javascript, here are some resources to check out: