Tải bản đầy đủ (.pdf) (15 trang)

JQuery: Novice to Ninja- P6 doc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (579.26 KB, 15 trang )

Licensed to

52 jQuery: Novice to Ninja
Animating CSS Properties
We have mastered some valuable examples of animation so far—sliding, fading,
and some fancy hiding and showing—but we haven’t had a lot of control over what
exactly is animated and exactly how it happens. It’s time to introduce a very exciting
jQuery function, helpfully called animate, which lets you animate a whole host of
CSS properties to fashion some striking effects of your own. Let’s have a look at an
example of animate in action:
chapter_03/01_animating_css/script.js (excerpt)
$('p').animate({
padding: '20px',
borderBottom: '3px solid #8f8f8f',
borderRight: '3px solid #bfbfbf'
}, 2000);
This code will animate all paragraphs on the page, changing the padding from its
initial state to 20px and adding a beveled border over a period of 2 seconds (2,000
milliseconds).
To use animate, we pass an object literal containing the properties we would like
to animate specified as key/value pairs—much the same as when you assign multiple
properties with the css function. There’s one caveat that you’ll need to remember:
property names must be camel-cased in order to be used by the animate function;
that is to say, you’ll need to write marginLeft, instead of margin-left and back-
groundColor
instead of background-color. Any property name made up of multiple
words needs to be modified in this way.
The time span parameter works exactly the same way as the simple animations we
saw in Chapter 2: you can pass a number of milliseconds, or one of the strings slow,
fast, or normal. Values for CSS properties can be set in pixels, ems, percentages,
or points. For example, you could write 100px, 10em, 50%, or 16pt.


Even more excitingly, the values you define can be relative to the element’s current
values: all you need to do is specify += or -= in front of the value, and that value
will be added to or subtracted from the element’s current property. Let’s use this
ability to make our navigation menu swing as we pass our mouse over the menu
items using the hover function:
Licensed to
Licensed to



Animating, Scrolling, and Resizing 53
chapter_03/02_relative_css_animation/script.js (excerpt)
$('#navigation li').hover(function() {
$(this).animate({paddingLeft: '+=15px'}, 200);
}, function() {
$(this).animate({paddingLeft: '-=15px'
}, 200);
});
Mouse over the navigation menu, and you’ll see the links wobble around nicely.
You can also use animate to achieve fine-grained control over the showing, hiding,
and toggling functions we saw in Chapter 2. We simply specify a property’s anima-
tion value as show, hide, or toggle rather than a numeric amount:
chapter_03/03_animate_show_hide (excerpt)
$('#disclaimer').animate({
opacity: 'hide',
height: 'hide'
}, 'slow');
It’s terribly satisfying seeing elements animate. As an exercise, try animating every
element property you can think of—you’ll stumble on some interesting effects! The
animate function also has some powerful advanced options, which we’ll examine

in detail over the course of this chapter.
Color Animation
Once you realize how cool the animate function is, you’ll probably want to animate
an element’s color. However, animating color is a little bit tricky, because the color
values “in between” the start and end colors need to be calculated in a special way.
Unlike a height or width value that moves from one value to another in a simple,
linear manner, jQuery needs to do some extra math to figure out what color is, say,
three-quarters of the way between light blue and orange.
This color-calculating functionality is omitted from the core library. This makes
sense when you think about it: most projects have no need for this functionality,
so jQuery can keep the size of the core library to a minimum. If you want to animate
color, you’re going to need to download the Color Animations plugin.
1
1

Licensed to
Licensed to


54 jQuery: Novice to Ninja
Using Plugins
The official jQuery plugin repository
2
contains an ever-increasing number of
plugins—some more useful than others. You can search for plugins by name,
category (such as effects or utilities), or by the rating it’s received from the jQuery
community.
Once you’ve found a plugin you’re interested in, download it to a suitable location
for your project (most likely the same place as your jQuery source file). It’s a good
idea to peruse the

readme file or related documentation before you use a plugin,
but generally all you need to do is include it in your HTML files, in much the
same way as we’ve been including our custom JavaScript file.
How you make use of your newfound functionality varies from plugin to plugin,
so you’ll have to consult each plugin’s documentation to put it to the best use.
After downloading and including the Color Animations plugin, you can now animate
color properties in your jQuery animation code, just as you would other CSS prop-
erties. Let’s gradually highlight our disclaimer message over a period of two seconds
as the page loads, to make sure no one misses it:
chapter_03/04_color_animation (excerpt)
$('#disclaimer').animate({'backgroundColor':'#ff9f5f'}, 2000);
See how animating the disclaimer makes it so much more noticeable?
Easing
Easing refers to the acceleration and deceleration that occurs during an animation
to give it a more natural feel. Easing applies a mathematical algorithm to alter the
speed of an animation as it progresses. Thankfully, we’re using jQuery, so you can
leave your high school math skills safely locked away.
There are two types of easing available to use in jQuery: linear and swing. Any
time you use an animation function in jQuery, you can specify either of these
parameters to control the animation’s easing. The difference between them can be
2

Licensed to
Licensed to
Animating, Scrolling, and Resizing 55
seen in Figure 3.1, which shows how a property is adjusted over the period of an
animation depending on which easing option you select.
Figure 3.1. jQuery’s easing options
swing easing starts off slowly before gaining speed, then towards the end of the
animation it slows down again, nice and gently. Visually, swing easing looks far

more natural than linear easing, and jQuery uses it by default if no easing parameter
is specified.
The linear easing method has no acceleration or deceleration: animations occur at
a constant rate. It looks fairly boring and a bit rigid in most circumstances, but it’s
worth giving it a try—it might just be appropriate for your purposes.
As an example, we’ll animate the first paragraph tag so that when clicked, it grows
and shrinks; we’ll use linear easing as it grows, and swing easing as it shrinks. The
difference is quite subtle, but if you repeat the animations a few times you should
be able to distinguish between them; the shrinking animation feels a little bit more
natural:
chapter_03/05_easing/script.js (excerpt)
$('p:first').toggle(function() {
$(this).animate({'height':'+=150px'}, 1000, 'linear');
}, function() {
$(this).animate({'height':'-=150px'}, 1000, 'swing');
});
There’s quite a lot of jQuery in this statement, so now might be a good time to pause
and make sure you understand everything that’s going on here:
Licensed to
Licensed to







56 jQuery: Novice to Ninja

We use a filter with a selector to grab only the first paragraph tag.


A toggle event handler (which executes each passed function on successive
clicks) is attached to the paragraph.

Inside the handlers we select this, which refers to the element that triggered
the event (in our example, it’s the paragraph itself).

The first handler uses the += format to grow the paragraph’s height by 300 pixels,
using the linear easing function.

The second handler uses the -= format to shrink the paragraph’s height by 300
pixels, using the swing easing function.
If you managed to follow along and understand each of these steps, pat yourself on
the back! You’re really getting the hang of jQuery!
Advanced Easing
As stated, swing easing provides a much more visually pleasing transition, and is
probably adequate for most tasks. But swing and linear easing are just the tip of the
iceberg. There is a vast array of easing options beyond these two basic types included
in the core jQuery library. Most of these are available in the easing plugin,
3
available
from the jQuery plugin repository.
jQuery UI Includes Several Plugins
The easing library is also included in the effects section of the jQuery UI library,
which we’ll be visiting shortly. If you’re starting to suffer from plugin fatigue,
then you might like to skip forward to the section called “The jQuery User Interface
Library”—this library includes several common plugins, including color animation,
class transitions, and easing. By including the jQuery UI library, you
’ll avoid
needing to include each plugin separately in your pages.

Just download and include the plugin’s JavaScript file in your HTML page, anywhere
after the jQuery library. Rather than providing you with new functions, the easing
plugin simply gives you access to over 30 new easing options. Explaining what all
of these easing functions do would test even the most imaginative writer, so we’ll
3

Licensed to
Licensed to



Animating, Scrolling, and Resizing 57
simply direct your attention to Figure 3.2, where you can see a few of the algorithms
represented graphically.
You’ll notice that some of the algorithms move out of the graph area; when animated
elements reach this part of the transition, they’ll move past their destination and
finally turn back to settle there. The effect is that of an element attached to a piece
of elastic, which gently pulls everything back into place.
Figure 3.2. Advanced easing options
To use one of the new algorithms, we just need to pass its name to our animate
function. There are lots to choose from, so we might as well jump straight into it
and try a few different ones:
chapter_03/06_other_easing_options/script.js (excerpt)
$('p:first').animate({height: '+=300px'}, 2000, 'easeOutBounce');
$('p:first').animate({height: '-=300px'}, 2000, 'easeInOutExpo');
$('p:first').animate({height: 'hide'}, 2000, 'easeOutCirc');
$('p:first').animate({height: 'show'}, 2000, 'easeOutElastic');
Look at that paragraph go! You might want to know where these easing option names
are coming from—or where you can see the full list. The algorithms originated from
Robert Penner’s easing equations, which are described in detail on his web site.

4
4

Licensed to
Licensed to


58 jQuery: Novice to Ninja
The best way to see all the available equations is to view the plugin’s source code.
If you use your text editor to open up the file you downloaded, you’ll see a list of
the functions you can use in jQuery animations.
Time to Play Around
Take a break and test out all of the easing functions that the plugin makes available.
It’s unlikely you’ll ever need to use all of them, but becoming familiar with them
will let you choose the right one to give your interface the precise feel you want.
Moreover, playing around with the animate function will cement your knowledge
of it: it’s an important part of a jQuery ninja’s arsenal!
Bouncy Content Panes
Now that we’ve learned a bit about how the animate function works, let’s have a
look at our client’s latest round of requests. Today’s to-do list includes the addition
of a vitally important page component: the StarTrackr! Daily “Who’s Hot Right
Now?” List (or the SDWHRNL for short). The list consists of the latest celebrities to
fall in or out of favor, along with an accompanying photo and brief bio. We’ll apply
some of the animation and easing techniques we’ve just learned to implement the
list as panes that can be opened and closed independently.
The appearance of the widget in the page is shown in Figure 3.3.
Figure 3.3. Biography panes
Licensed to
Licensed to
Animating, Scrolling, and Resizing 59

In our HTML, we’ll implement the section as a div element containing all of our
celebrities. Each celebrity’s pane will be marked up as an h3, followed by another
div containing an image and a short paragraph:
chapter_03/07_bouncy_content_panes/index.html (excerpt)
<div id="bio">
<h2>Who’s Hot Right Now?</h2>
<h3>Beau Dandy</h3>
<div>
<img src=" /images/beau_100.jpg" width="100"
height="100" alt="Beau Dandy"/>
<p>Content about Beau Dandy</p>
</div>
<h3>Johnny Stardust</h3>
<div>
<img src=" /images/johnny_100.jpg" width="100"
height="100" alt="Johny Stardust"/>
<p>Content about Johny Stardust</p>
</div>
<h3>Glendatronix</h3>
<div>
<img src=" /images/glenda_100.jpg" width="100"
height="100" alt="Glendatronix"/>
<p>Content about Glendatronix</p>
</div>
</div>
When a user clicks on one of the headings, we want the associated content pane to
toggle open and closed. You can style your panes however you see fit, but having
a block-level element for a heading with a different-colored background is a common
technique: it provides a clear call to action for the user to click on it.
“Jumpy” Animation?

One quirk to be aware of is that animating an element directly next to a heading
tag can sometimes look “jumpy”—especially when the element hides. This is due
to the heading’s margin, which collapses as the following element hides. A simple
workaround, which we’ve used here, is to remove margins from the heading tag
entirely.
Licensed to
Licensed to




60 jQuery: Novice to Ninja
We want to avoid showing any content when the page loads, so the first thing to do
is to hide all of the content containers:
chapter_03/07_bouncy_content_panes/script.js (excerpt)
$('#bio > div').hide();
If, instead, you’d prefer to have one pane open by default, you could specify it here.
This can help to make it more evident to users that there’s content “hidden” in the
panes, and that they’re meant to click on the headings to reveal it. Making this work
in jQuery is simple: we merely apply the :first filter and call the show action to
reveal only the first pane:
$('#bio > div:first').show();
The Child Selector
There’s a new selector feature in these examples that we’ve yet to cover. It’s the
child selector, and it’s indicated by the greater-than angle bracket (>). A child se-
lector selects all the immediate children that match the selector. If we’d omitted
the child selector, our code would select all div elements underneath the bio div
element, even if they were nested inside other elements. For more details and
code examples using this selector, feel free to look it up in the jQuery API docu-
mentation.

5
Now that our content is marked up the way we want it, we simply need to add some
jQuery interaction magic to it. To reveal our secret content we’ll take the familiar
approach of capturing the click event, finding the next element (which contains
our content), and showing it—as we did in Chapter 2. But this time, we’ll employ
a touch of “bounce,” easing to the content’s height so that the panes bounce in and
out of view:
5

Licensed to
Licensed to
Animating, Scrolling, and Resizing 61
chapter_03/example_07/script.js (excerpt)
$('#bio h3').click(function() {
$(this).next().animate(
{'height':'toggle'}, 'slow', 'easeOutBounce'
);
});
The easing function easeOutBounce produces a great bouncing ball effect, which
works wonderfully for content panes like this. Give it a spin in your browser and
see for yourself!
The Animation Queue
The last topic we’re going to look at with regards to animation is another advanced
use of the animate function. It turns out animate can be called with a set of extra
options, like this:
animate(parameters, options);
The options parameter is a bundle of options packaged together as an object literal
made up of key/value pairs. We’re already familiar with several of the available
options: duration, easing, and complete (the callback method). There are, however,
a couple of new ones: step and queue. Before we explain them, let’s take a look at

the syntax for calling the animate function with an options parameter:
chapter_03/08_animation_queue/script.js (excerpt)
$('p:first').animate(
{
height: '+=100px',
backgroundColor: 'green'
},
{
duration: 'slow',
easing: 'swing',
complete: function() {alert('done!');},
queue: false
}
);
Licensed to
Licensed to
62 jQuery: Novice to Ninja
Notice that you can accomplish almost all of this with the simpler format that we’ve
already seen. You only need the advanced version if you want to specify additional
settings, like the queue parameter.
The queue is the list of animations waiting to occur on a particular element. Every
time we ask jQuery to perform an animation on an element, that animation is added
to the queue. The element executes the queue one at a time until everything is
complete. You’ve probably already seen this if you’ve gone click-happy on one of
our demos.
There are many situations where this will be undesirable though. Sometimes you’ll
want multiple animations to occur at the same time. If you disable the queue when
you specify an animation, further animations can run in parallel.
The animation queue can be controlled by using the queue option, as well as with
the jQuery actions stop, queue, and dequeue. This combination of actions and op-

tions gives us super-fine control over how our animations run. But before we can
really sink our teeth into these juicy options, it’s time to unveil one of the most
important jQuery techniques around.
Chaining Actions
So far we’ve been writing statements one at a time—either one after the other, or
nested inside callback functions. We’ve needed to either rewrite our selectors, or
make use of the this keyword to find our targets again. However, there’s a technique
that allows us to run multiple jQuery commands, one after the other, on the same
element(s). We call this chaining—and to release the ninja inside of you, you’d
better pay attention to this bit.
Chaining links two or more jQuery actions into a single statement. To chain an action
you simply append it to the previous action. For example, let’s chain together the
hide, slideDown, and fadeOut actions. Our element quickly hides and then slides
into view, before fading away:
$('p:first').hide().slideDown('slow').fadeOut();
You can chain together as many actions as you like. Be careful though: chaining
can quickly become addictive! As well as being able to chain actions based on your
Licensed to
Licensed to
Animating, Scrolling, and Resizing 63
initial selector, you can also move around the DOM, adding and removing elements
as you go—which can lead to some quite hairy statements.
It’s often good to lay out your actions on separate lines for clarity. This takes up a
lot more space, but is much easier to read and maintain. Our previous example
could be rewritten like this:
$('p:first')
.hide()
.slideDown('slow')
.fadeOut();
It’s important to realize that the jQuery selector contains the modified results of

each action that runs before running the next action. This means that we can add
and remove elements as we go along, only applying actions to the current selection.
If you revisit a few of our earlier examples, you might spot a few chained actions
hidden in the code—for example, when we wrote: $(this).next().toggle(). The
next action moved our selection to the next DOM element, and then the toggle
action toggled it without affecting the original element.
You’ll have plenty of chances from now on to play with chaining; the rest of this
book is going to be filled with it. It’s the most fun part of jQuery!
Pausing the Chain
If you’d like to pause briefly in the middle of a jQuery chain, you can use the delay
action. Simply give it a number, and it will hold the chain for that many milliseconds
before continuing. So, referring to the same example, we could write:
$('p:first')
.hide()
.slideDown('slow')
.delay(2000)
.fadeOut();
This code will slide down the paragraph, and then wait two seconds before fading
it out. This can be a great way to control your animations more precisely.
Licensed to
Licensed to



64 jQuery: Novice to Ninja
Animated Navigation
The client is sticking to his guns on this issue: he wants the top-level navigation to
be a Flash control that wobbles and zooms around as the user interacts with it.
Flash, he explains, looks better. You assure him your Flash skills are second to
none, and that you’ll whip up a proof of concept for him right away.

Okay. Now, with the client out of the room, let’s apply our newly discovered jQuery
power to create a Flash-like navigation bar. It will have a background “blob” that
wobbles around to highlight the menu choice the user is hovering over. And we’ll
do it all with free, standard technologies: HTML, CSS, and JavaScript. Flash? We
don’t need no stinkin’ Flash!
We’re sticking with a fairly basic animation so that the steps are easier to follow.
First off, we’ve modified the CSS pertaining to our navigation menu so that it’s laid
out horizontally rather than vertically. As a refresher, here’s what the HTML for the
navigation looks like:
chapter_03/09_animated_navigation/index.html (excerpt)
<ul id="navigation">
<li><a href="#">Home</a></li>
<li><a href="#">About Us</a></li>
<li><a href="#">Buy!</a></li>
<li><a href="#">Gift Ideas</a></li>
</ul>
Our background color blob will be an empty div element, positioned behind
whichever navigation link the user is mousing over. Our first task, therefore, will
be to create the element and append it to the document:
chapter_03/09_animated_navigation/script.js (excerpt)
$('<div id="navigation_blob"></div>').css({
width: $('#navigation li:first a').width() + 10,
height: $('#navigation li:first a').height() + 10
}).appendTo('#navigation');
Notice that we’re selecting the navigation link inside the object literal to provide
values for the width and height. This may seem strange if you’re new to program-
ming, but you shouldn’t let it frighten you—in general, you can use the returned
Licensed to
Licensed to







Animating, Scrolling, and Resizing 65
(or calculated) value of a function anywhere you can put a static value. We’re also
adding 10 to each of those values, so that the blob is slightly larger than the anchor
tag it will sit behind.
With the blob in place, we need to set up a trigger that will set it in motion. This
should occur when the user hovers over one of the navigation links, so we’ll use
the hover function. Remember that hover accepts two parameters: the function that
runs when the mouse moves over the element, and the one that runs when the
mouse moves off the element. This is the general outline of our event handler:
chapter_03/09_animated_navigation/script.js (excerpt)
$('#navigation a').hover(function() {
// Mouse over function

}, function() {
// Mouse out function

});
Now for some fun stuff. Let’s look at the first function, which occurs when the
mouse moves over the element:
chapter_03/09_animated_navigation/script.js (excerpt)
// Mouse over function
$('#navigation_blob').animate(
{width: $(this).width() + 10, left: $(this).position().left},
{duration: 'slow', easing: 'easeOutElastic', queue: false}
);

When the user mouses over the menu item, we animate two properties of the blob:
its width and its position.
The link’s position on the page can be determined using a jQuery method called
position. This is an action that does nothing on its own, but when called exposes
two properties: left and top; these are the left and top offsets of the selected element
relative to its parent. In this case we want the left property, so we know where to
move the blob to in our navigation menu.
Licensed to
Licensed to

66 jQuery: Novice to Ninja
We set the queue option to false to ensure that our animations won’t pile up in a
line waiting to execute if our user is hover-happy. When you move to a different
link, a new animation will start regardless of whether the current one is finished
or not.
We still need to tell jQuery what to do when our user moves the mouse off the link.
This block of code is fairly similar to the one we just saw, although it includes a
few more chained actions:
chapter_03/09_animated_navigation/script.js (excerpt)
// Mouse out function
$('#navigation_blob')
.stop(true)
.animate(
{width: 'hide'},
{duration: 'slow', easing: 'easeOutCirc', queue: false}
)
.animate(
{left: $('#navigation li:first a').position().left;},
'fast'
);

}
This time we’ve chained two animate actions together: the first one hides the blob
with a bit of nice easing applied, and the second whisks it off to the side (to the
position of the first link in the navigation).
You might notice that there’s an extra action chained into our animation, the stop
action. stop does exactly what you’d expect—it stops the animation! It accepts two
optional parameters: clearQueue and gotoEnd. We’re setting the clearQueue para-
meter to true, so that any queued animations are cleared.
The gotoEnd parameter is used if you want jQuery to determine what an element’s
state will be at the end of the current animation queue, and then jump immediately
to that state. We don’t want to use that here, as we want our animations to start from
the blob’s current position—even if it’s only halfway through moving.
Give the menu a spin in your browser, and see how the appropriate use of easing
has given our control a natural feel.
Licensed to

×