In last
week’s article, we covered the most basic jQuery concepts. We’ve
learned the steps to use the jQuery statement: make sure the document is
ready, select elements, and change them. In this article, we’ll apply these
lessons to implement some cool and useful effects—to reinforce your
understanding of the jQuery basics.
This article is also taken from Chapter 2 of jQuery: Novice to
Ninja by Earle Castledine and Craig Sharkie. You can
download all of
Chapters 1, 2, and 7 as a free PDF here. The download also includes
the code archive for the whole book, so be sure to grab it if you want to
follow along with the examples in this article.
The client dislikes the disclaimer on the site—he feels it
reflects badly on the product—but his lawyer insists that it’s necessary.
So the client has requested that you add a button that will remove the
text after the user has had a chance to read it:
Example 1. chapter_02/11_hiding/index.html
(excerpt)
<input type="button" id="hideButton" value="hide" />
We’ve added an HTML button on the page with an ID of hideButton. When a user clicks on this button
we want the disclaimer element, which has an ID of disclaimer, to be hidden:
Example 2. chapter_02/11_hiding/script.js
(excerpt)
$('#hideButton').click(function() {
$('#disclaimer').hide();
});Run this code and make sure the disclaimer element disappears when
you click the hide button.
The part in this example that makes the element actually disappear
is the hide action. So, you might ask, what’s all the other code that surrounds
that line? It’s what’s called an event handler—an understanding of which
is crucial to becoming a jQuery ninja. There are many event handlers we
can use (we’ve used the click event handler here) and
we’ll be using a lot of them as we move on.
Event handlers are named for their function of handling events. Events are
actions and user interactions that occur on the web page. When an event
happens, we say that it has fired. And when we write
some code to handle the event, we say we caught the
event.
There are thousands of events fired on a web page all the time: when
a user moves the mouse, or clicks a button, or when a browser window is
resized, or the scroll bar moved. We can catch, and act on, any of these
events.
The first event that you were introduced to in this book was the
document-ready event. Yes, that was an event handler: when the document
said, “I’m ready” it fired an event, which our jQuery statement
caught.
We used the click event handler to tell jQuery to hide the disclaimer when the button is
clicked:
$('#hideButton').click(function() {
$('#disclaimer').hide();
});When an event fires, we will often want to refer to the
element that fired it. For example, we might want to modify the button
that the user has just clicked on in some way. Such a reference is
available inside our event handler code via the JavaScript keyword
this. To convert the JavaScript object to a jQuery
object, we wrap it in the jQuery selector:
Example 3. chapter_02/12_this/script.js
(excerpt)
$('#hideButton').click(function() {
$(this).hide(); // a curious disappearing button.
});$(this) provides a nicer way to talk about the
element that fired the event, rather than having to re-select it.
This might be a bit confusing when you’re starting out, as
the “action” component of a jQuery statement seems to have several
purposes: we’ve seen it used to run animations, retrieve values and now,
handle events! It’s true—it gets around! Usually the action’s name gives
you a good clue to its purpose, but if you become lost, it’s best to
consult the index. After a while, you’ll sort out the handlers from the
animations from the utilities.
On with our task! The client has also specified that the user needs
to be able to retrieve the disclaimer in case they close it by mistake. So
let’s add another button to the HTML, this time with an id of showButton:
Example 4. chapter_02/13_revealing/index.html
(excerpt)
<input type="button" id="showButton" value="show" />
We’ll also add another jQuery statement to our script file, to
handle showing the disclaimer when the button
is clicked:
Example 5. chapter_02/13_revealing/script.js
(excerpt)
$('#showButton').click(function() {
$('#disclaimer').show();
});Having separate buttons for hiding and showing the
disclaimer seems like a waste of valuable screen real estate. It would be
better to have one button that performed both tasks—hiding the disclaimer
when it’s visible, and showing it when it’s hidden. One way we could do
this is by checking if the element is visible or not, and then showing or
hiding accordingly. We’ll remove the old buttons and add this nice new
one:
Example 6. chapter_02/14_toggle_1/index.html
(excerpt)
<input type="button" id="toggleButton" value="toggle" />
When it’s clicked, we check to find out if we should show or hide
the disclaimer:
Example 7. chapter_02/14_toggle_1/script.js
(excerpt)
$('#toggleButton').click(function() {
if ($('#disclaimer').is(':visible')) {
$('#disclaimer').hide();
} else {
$('#disclaimer').show();
}
});This introduces the is action. is takes any of the same selectors
we normally pass to the jQuery function, and checks to see if they match
the elements it was called on. In this case, we’re checking to see if our
selected #disclaimer is also selected by the
pseudo-selector :visible. It can also be used to check
for other attributes: if a selection is a form or div,
or is enabled.
If you’re entirely new to programming (that is, if you’ve
only ever worked with HTML and CSS), that whole block of code is
probably quite confusing! Don’t worry, it’s actually quite
straightforward:
if (condition) {
// this part happens if the condition is true
} else {
// this part happens if the condition is false
}The condition can be anything that JavaScript will evaluate to
true or false. This sort of
structure is extremely common in any type of programming, and we’ll be
using it a lot for the rest of the book. If you’re uncomfortable with
it, the best way to learn is to play around: try writing different
if / else blocks using jQuery’s
is action like the one we wrote above. You’ll
get the hang of it in no time!
is will return true or
false depending on whether the elements match the
selector. For our purposes we’ll show the element if it’s hidden, and hide
it if it’s visible. This type of logic—where we flip between two states—is
called a toggle and is a very useful construct.
Toggling elements between two states is so common that many jQuery
functions have a version that allows for toggling. The toggle version of
show/hide is simply
called toggle, and works like this:
Example 8. chapter_02/15_toggle_2/script.js
(excerpt)
$('#toggleButton').click(function() {
$('#disclaimer').toggle();
});Every time you click the button, the element toggles between visible
and hidden.
It would be nice, however, if the button was labeled with a more
useful word than “toggle,” which might be confusing to our users. What if
you want to toggle the text of the button as well? As is often the case
when working with jQuery, there are a few ways we could approach this
problem. Here’s one:
Example 9. chapter_02/16_toggle_text/script.js
(excerpt)
$('#toggleButton').click(function() {
$('#disclaimer').toggle();
if ($('#disclaimer').is(':visible')) {
$(this).val('Hide');
} else {
$(this).val('Show');
}
});There’s a lot in this code that will be new to you. We’ll save most
of the details for later, but have a look at it and see if you can figure
it out yourself. (Hint: remember that the selector
$(this) refers to the element that caused the event to
fire—in this case, the button.)
Our disclaimer functionality is working perfectly—and our
client will doubtlessly be impressed with it. However, there’s one subtle
aspect of our solution that we should be aware of: if a user came to our
site using a browser lacking support for JavaScript, they’d see a button
on the page that would do nothing when they clicked it. This would lead to
a very confused user, who might even abandon our site.
“No support for JavaScript?” you might snort. “What kind of browser
is unable to run JavaScript?!”
There might be more people than you think browsing the Web without
JavaScript: users on very old computers or limited devices (like mobile
phones); people with visual impairments who require screen readers to use
the Web; and those who worry that JavaScript is an unnecessary security
risk and so choose to disable it.
Depending on your site’s demographic, anywhere between 5% and 10% of
your users might be browsing without JavaScript capabilities, and nobody
wants to alienate 10% of their customers! The solution is to provide an
acceptable experience to these users—and beef it up for everyone else.
This practice is known as progressive enhancement.
For our disclaimer functionality, we might settle on this
compromise: we want the disclaimer to be visible to all users, so we place
it in our HTML. Then, we add the ability to hide it for users with
JavaScript. That said, we’d prefer to avoid displaying the show/hide
button to users who’ll be unable to make use of it.
One way of accomplishing this might be to hide our button with CSS,
and only show it via a jQuery css statement. The
problem with this trick is that it will fail if the user’s browser also
lacks support for CSS. What we’d really like to do is add the button to
the page via jQuery; that way, only users with JavaScript will see the
button at all. Perfect!
So far we’ve seen the jQuery function used for selecting,
but it does have another function of equal importance: creating new
elements. In fact, any valid HTML string you put inside the jQuery
function will be created and made ready for you to stick on the page.
Here’s how we might create a simple paragraph element:
$('<p>A new paragraph!</p>')jQuery performs several useful actions when you write this code: it
parses the HTML into a DOM fragment and selects it—just as an ordinary
jQuery selector does. That means it’s instantly ready for further jQuery
processing. For example, to add a class to our newly created element, we can
simply write:
$('<p>A new paragraph!</p>').addClass('new');The new paragraph will now be given the class new.
Using this method you can create any new elements you need via jQuery
itself, rather than defining them in your HTML markup. This way, we can
complete our goal of progressively enhancing our page.
Internally, the HTML string is parsed by creating a simple element
(such as a div) and setting the
innerHTML property of that div to the markup you provide. Some content
you pass in is unable to convert quite as easily—so it’s best to keep
the HTML fragments as simple as possible.
Once we’ve created our new elements, we need a way to insert in the
page where we’d like them to go. There are several jQuery functions
available for this purpose. The first one we’ll look at is the
insertAfter function. insertAfter will take our current
jQuery selection (in this case, our newly created elements) and insert it
after another selected element, which we pass as a parameter to the
function.
An example is the easiest way to show how this works. This is how
we’d create the toggle button using jQuery:
Example 10. chapter_02/17_insert_after/script.js
(excerpt)
$('<input type="button" value="toggle" id="toggleButton">')
.insertAfter('#disclaimer');
$('#toggleButton').click(function() {
$('#disclaimer').toggle();
});As shown in Figure 1, “A button created and inserted with jQuery”, the button is
inserted into our page after the disclaimer, just as if we’d put it there
in our HTML file.
The insertAfter function adds the new element
as a sibling directly after the disclaimer element. If you want the button
to appear before the disclaimer element, you could
either target the element before the disclaimer and use
insertAfter, or, more logically, use the
insertBefore method. insertBefore will also place the
new element as a sibling to the existing element, but it will appear
immediately before it:
Example 11. chapter_02/18_insert_before/script.js
(excerpt)
$('<input type="button" value="toggle" id="toggleButton">')
.insertBefore('#disclaimer');A quick refresher: when we talk about the DOM, siblings refer to elements on the
same level in the DOM hierarchy. If you have a div that contains two span elements, the span elements are siblings.
If you want to add your new element as a child
of an existing element (that is, if you want the new element to appear
inside the existing element) then you can use the
prependTo or appendTo
functions:
Example 12. chapter_02/19_prepend_append/script.js
(excerpt)
$('<strong>START!</strong>').prependTo('#disclaimer');
$('<strong>END!</strong>').appendTo('#disclaimer');As you can see in Figure 2, “prependTo and
appendTo in action”, our new
elements have been added to the start and the end of the actual disclaimer
div, rather than before or after it.
There are more actions for inserting and removing elements, but as they’re
unneeded in this round of changes, we’ll address them later on.






