JQuery: Novice to Ninja- P7

JQuery: Novice to Ninja- P7

JQuery: Novice to Ninja- P7:No matter what kind of ninja you are—a cooking ninja, a corporate lawyer ninja, or an actual ninja ninja—virtuosity lies in first mastering the basic tools of the trade. Once conquered, it’s then up to the full-fledged ninja to apply that knowledge in creative and inventive ways.

Nội dung Text: JQuery: Novice to Ninja- P7

Animating, Scrolling, and Resizing 67
Now’s a great time to try some different easing functions. Just replace the ones used
here with any of the others from the easing plugin—you’ll be amazed at how much
difference they make to the feel of the component. You can also try animating other
values: changing the blob’s color, for instance.
Animated Navigation, Take 2
One of the great advantages to using a library such as jQuery is that you can try out
a bunch of different alternatives fairly quickly, and pick the one you like best.
We still have a few hours left before our client will want to see the progress of our
animated navigation. Let’s try to approach the same problem from a different angle
and see what we can come up with.
Licensed to JamesCarlson@aol.com
For this animation, our menu items will each have a hidden icon that will bounce
into view when the link is moused over (as shown in Figure 3.4).
Figure 3.4. Bouncy animated menu
The setup for this effect is nice and simple. It’s a regular unordered list, configured
as a horizontal menu—but we’ve stashed a secret icon underneath the normally
visible area. This is just a matter of setting the list item’s height so that you can only
see the link text by default, but as we animate the height the icon bounces into view.
We’ll start with the CSS: we’ve moved our menu to be absolutely positioned at the
top-right of the container div, where there’s space for the icons to expand. We’ve
set a background color for the icons to be set against, and employed a clever trick
to keep the background images out of view; notice that the list items are 20px in
height, but that the background is offset 30px from the top. As a result, they’ll be
invisible until we expand the height of the list items.
We’ll also set the background image of each link to a different icon:

68 jQuery: Novice to Ninja
chapter_03/10_animated_navigation_2/navigation.css (excerpt)
#container {
position: relative;
}
#navigation {
position:absolute;
width: inherit;
top: 0;
right: 0;
margin: 0;
}
Licensed to JamesCarlson@aol.com
#navigation li {
height:20px;
float:left;
list-style-type: none;
width:70px;
padding:3px;
border-right:1px solid #3687AF;
background-color: #015287;
background-repeat: no-repeat;
background-position: center 30px;
}
#navigation li a {
color: #FFFFFF;
}
#navigation #home{
background-image:url('icon_home.png');
}
⋮
The only new aspect for this effect’s code is that we use the stop action to clear the
queue for both the mouseover event and the mouseout event. Then we just animate
the height to display the hidden icons and shrink it back to normal when the hover
finishes. Some carefully chosen duration and easing settings give us the groovy
bouncing effect that we’re after. Make sure you experiment with the settings in order
to match the feel of your site:

Animating, Scrolling, and Resizing 69
chapter_03/10_animated_navigation_2/script.js (excerpt)
$('#nav_stretch li').hover(
function() {
$(this)
.stop(true)
.animate(
{height: '60px'},
{duration: 500, easing: 'easeOutBounce'}
)
},
function() {
$(this)
.stop(true)
Licensed to JamesCarlson@aol.com
.animate(
{height:'20px'},
{duration: 500, easing: 'easeOutCirc'}
)
}
);
Now we have not one, but two funky examples of animated navigation to show our
client!
The jQuery User Interface Library
As mentioned in Chapter 1, the jQuery UI library is a collection of advanced jQuery
widgets, effects, and interactions—such as date pickers, accordions, and drag-and­
drop functionality—that are widely applicable to web development. But before we
start the fun stuff, it’s time to have a look at downloading and including the jQuery
UI library—a procedure that’s marginally more complicated to set up than the core
library and plugins we’ve been using so far. This is because the full jQuery UI library
is nearly 500KB in size (300KB when minified)! That’s a lot of code! Fortunately,
any given project will normally only require a small subset of the functionality
contained in jQuery UI, and the jQuery web site provides us with a handy tool to
create our own custom version of jQuery UI that contains only what we need and
nothing more.

70 jQuery: Novice to Ninja
The options can appear a bit daunting the first time you visit the download builder
page, which you can reach by clicking the Build custom download link from the jQuery
UI homepage.6
The download builder is broken into several sections: Core, Interaction, Widgets,
Effects, and Themes. Core is the main jQuery UI library—the Widgets and Interaction
components all rely on it. A good way to approach the builder is to deselect
everything and then add only what you require. If a component relies on another
component to function,it will be automatically selected for you.
While we’re developing, it’s safe to grab the full library. That way everything will
be there for us to use if we need it. Once you’re happy with the functionality on
Licensed to JamesCarlson@aol.com
your web site, you can always return to the download builder and create a custom
library, omitting anything unused. The difference in file size between the full library
and a customized version can be quite significant, as illustrated in Figure 3.5.
Figure 3.5. Full jQuery UI library versus customized download
One option that will greatly affect the visual output of the widgets and interactions
is the theme. There are a number of themes you can choose from using the drop-
down box. In Chapter 9 we’ll have an in-depth look at themes, including making
your own. But in the interests of progressing with the more exciting stuff, we’ll use
the default theme and return to work.
6
http://jqueryui.com/

Animating, Scrolling, and Resizing 71
The custom download archive contains a lot of files. There are heaps of demos and
documentation for you to try out and explore in the development-bundle directory,
but to use jQuery UI you’ll simply need the jQuery-ui-1.7.2-min.js file (or whichever
version is current at the time you’re reading this), and the directory that contains
the theme you’ve chosen.
You’ll have to put the theme’s directory in a location where your HTML page can
reach it. For this book’s examples, jQuery UI has been placed in the lib directory
(alongside jQuery itself), and the theme files in the css directory.
The jQuery UI library contains an Effects package that enables us to implement
some interesting effects. It also includes useful methods and functionality for doing
Licensed to JamesCarlson@aol.com
advanced animation. We’ve seen some of this functionality already, thanks to the
Color Animation plugin and the Easing plugin. These are included in the Effects
package, so you no longer need to include them if you’re going to use the jQuery
UI effects library.
Before we move on, let’s just have a quick look at a few of the available effects. We’ll
take our much-maligned first paragraph element and shake it about, highlight it in
yellow, then explode it to pieces:
chapter_03/11_jquery_ui_effects/script.js (excerpt)
$('p:first')
.effect('shake', {times:3}, 300)
.effect('highlight', {}, 3000)
.hide('explode', {}, 1000);
Look at it go! Of course, this is just a tiny sample of the available effects. Some of
them can only be used in this way, via the effect action, while others can be used
either in this way or in place of hide, show, or toggle parameters. Some examples
of the latter are blind, clip, puff, fold, and slide.
We’ll refrain from going through all of them in detail here—you’re best off spending
your Sunday afternoon exploring them. Not all of the effects are pure flair, however,
but many are useful in common user interaction scenarios, such as highlight,
which is a standard way to indicate a new message to the user.

72 jQuery: Novice to Ninja
It’s a good idea to test out each function, so you’ll remember them when they’re
appropriate. And if the jQuery UI assortment of effects just isn’t enough for you,
never mind—there are hundreds more available from the plugin repository!
Get Animated!
You now understand all the fundamentals of animating with jQuery: selectors, event
handlers, callbacks, chaining, and the all-important animate function. You’ve also
become briefly acquainted with the extensive jQuery UI library. The best way to
really master these skills, however, is to put them into practice. Go out and animate
everything you can get your hands on! Try playing with every property of every
element on every page, until you feel like you can really bend them to your will.
Licensed to JamesCarlson@aol.com
Before we move on from animation to the next jQuery skill set for you to master,
we’ll turn our attention to scrolling and resizing: these topics might be less flashy
than animation, but they’re essential to a good many user interface components.
They’ll also help cement your understanding of jQuery selectors, actions, and
chaining. So what are we waiting for?
Scrolling
Scrolling is, in a way, similar to animation, in that elements are moving around the
page. Unlike animation though, the user is the one in control! Still, there’s a plethora
of ways to customize these interactions. In this section, we’ll have a look at menus
that stay put when the user scrolls, custom-themed scrollbars, and even how we
can use the animation techniques we’ve just learned and apply them to scrolling
the document.
The scroll Event
Before we can improve our users’ scrolling experience, we need to know when and
what they are scrolling. It turns out there is an event, called scroll, which fires
when the user updates the scroll position of an element—such as the window or a
scrollable div. So, every time one of your users interacts with a scroll bar on your
site, an event will be fired that you can catch and respond to.
To capture the scroll event, we attach an event handler to an element that has
scroll bars—most often the window element. The window itself is a JavaScript object,
so all we need to do is wrap it in our jQuery function to select it.

Animating, Scrolling, and Resizing 73
Of course, to see the scroll event in action, we have to set up an area with scroll
bars! We have a few ideas for scrolling effects that we’d like to pitch to the client,
but in the interests of learning how the scroll event works, let’s just fake a scrolling
environment by setting overflow: scroll; on one of the divs in our page:
chapter_03/12_scroll_event/scroll.css (excerpt)
#news {
height: 100px;
width: 300px;
overflow: scroll;
}
Licensed to JamesCarlson@aol.com
This will turn our news section into a smaller scrolling pane inside the page. Now
let’s capture the scroll event and add some arbitrary text to the page every time
the scroll event fires:
chapter_03/12_scroll_event/script.js (excerpt)
$('#news').scroll(function() {
$('#header')
.append('You scrolled!');
});
Now whenever you scroll the news section, the text “You Scrolled!” will appear
on a red background at the top of the page. Very annoying, but you get the picture.
Try scrolling in different ways: dragging the scroll bar, using the mouse wheel, and
clicking inside the scrollable zone to use the arrow keys. In all the above cases, the
scroll event will fire.
Floating Navigation
We now know when a user scrolls, so how can we make use of this information to
improve our site? Well, one fairly common example of a page reacting to users’
scrolling is a floating navigation pane. This is when the main navigation element
is always present at the top of the visible part of the screen, regardless of the scroll
position; it’s as if the navigation menu follows users as they scroll down the page.
This is easy to implement using the scroll event: we simply need to find out where
we are on the page, and then move the navigation to that point.

74 jQuery: Novice to Ninja
Our first task is to set up our CSS to prepare for the animated navigation. We’ll add
a position: relative; declaration to our navigation element so that we can easily
move it up and down the page by adjusting its top property. For the purpose of this
exercise, we’ve applied a very large height property to the content in order to force
it to have a scroll bar (unless, of course, you have a huge monitor!):
chapter_03/13_floating_nav_1/scroll.css (excerpt)
#navigation {
position: relative;
}
#content {
Licensed to JamesCarlson@aol.com
height: 2000px;
}
Now we can take a stab at our floating pane. At first glance it seems that nothing
could be simpler—just respond to the scroll event of the main window by updating
the top position of the navigation block:
chapter_03/13_floating_nav_1/script.js (excerpt)
$(window).scroll(function() {
$('#navigation').css('top', $(document).scrollTop());
});
Test this out in your browser and you’ll see that we’ve achieved our goal: as you
scroll down the page, the navigation box plods along with you. How does it know
where the top is? We asked for the top of the screen by using the scrollTop action.
scrollTop returns the top offset of the matched element—in our example we asked
for the entire document’s top position: $(document).scrollTop(). This will always
be the very top of the screen.
It works, sure, but it’s very jumpy, which makes it a little unattractive. The reason
for this should be evident if you were paying attention when we first introduced
the scroll event: every time the user moves the scroll bar, it fires many scroll
events. Each one of those events triggers our code to update the navigation posi­
tion—so it’s no wonder the motion is jittery.
We saw how to stop animations from queuing up like this in the section called
“Animated Navigation” with the stop command. This takes care of the jumpiness,

Animating, Scrolling, and Resizing 75
but our effect could still use some refinement. How about we smarten it up with
some animation and a little bit of bouncy easing? Here’s how we do that:
chapter_03/14_floating_nav_2/script.js (excerpt)
$(window).scroll(function() {
$('#navigation')
.stop()
.animate({top: $(document).scrollTop()},'slow','easeOutBack');
});
For such a significant effect, it requires a satisfyingly minimal amount of code!
Scrolling the Document
Licensed to JamesCarlson@aol.com
When a long list of information about related (yet varied) subjects needs to be dis­
played on a single HTML page, it’s common to include a hyperlinked list of the
subjects at the top of the page.
These internal links will immediately jump to the correct position for the menu
item you selected. After the content, there’s often a link to take you back to the top
of the screen—so you can select another menu item. Let’s try adding this function­
ality to our page.
The first task is add the link to our page’s footer. To jump to the top of the page, all
we need to do is set our link’s href attribute to #.
If we think about it, all we want to do is animate the page’s scrolling position, which
is represented by scrollTop in jQuery. We’ll also need to cancel the default link
action—otherwise the page will jump before our animation has time to occur. If
you’re new to JavaScript, there’s an easy way to accomplish this: any function
handling a link’s click event need simply include the statement return false to
cancel the link’s default behavior:
$('a[href=#]').click(function() {
$('html').animate({scrollTop: 0},'slow');
return false; // Return false to cancel the default link action
}
This code introduces a new kind of selector: the attribute selector. By enclosing an
attribute and the value we want to look for in square brackets ([]), we can narrow

76 jQuery: Novice to Ninja
a selection to include only elements with a specific attribute value. In this case,
we’re looking for only those links with an href value of #.
This code works, and is certainly clear and simple, but it does encounter a slight
issue. If the user’s browser is operating in quirks mode, the $('html') selector will
fail. (Unsure what quirks mode means? Take the time to read the SitePoint CSS
reference page on the topic7 for a detailed explanation.) While you should be
marking up your pages in a way that triggers standards mode, sometimes you’ll be
working with legacy code and thus be without that luxury. To make the above code
work in quirks mode, you’d need to use the selector $('body'). We could also target
both, just to be sure: $('html, body'). This in turn causes issues in certain versions
of the Opera browser, which (probably correctly) tries to scroll both elements at the
Licensed to JamesCarlson@aol.com
same time.
“But you said jQuery sorts out all our cross-browser issues!” you might exclaim.
To be fair, it sorts out most cross-browser issues. This is a slightly trickier one, and
is not addressed in the core jQuery library. Fortunately for us, it’s fairly simple to
work around. Even more fortunately for us, someone has taken the time to package
that workaround (as well as a plethora of other scrolling functionality) into a plugin
called ScrollTo.
The ScrollTo plugin, available from the plugin repository,8 is a stable plugin for
scrolling the screen and overflowed elements. It’s more than capable of handling
any of the scrolling tasks we’ve seen so far.
After you’ve downloaded and included the plugin, you can rewrite the top link
functionality and forget all your worries about obscure browser bugs:
chapter_03/15_page_scroll/script.js (excerpt)
$('a[href=#]').click(function() {
$.scrollTo(0,'slow');
return false;
});
This syntax probably looks a little strange to you, in that we’re calling scrollTo
directly from the jQuery alias. The plugin is clever, and knows that if we call it
7
http://reference.sitepoint.com/css/doctypesniffing
8
http://plugins.jquery.com/project/ScrollTo

Animating, Scrolling, and Resizing 77
directly in this way, we want to scroll the entire window. If we wanted to scroll a
specific overflowed element, we’d use the traditional selector syntax, for example:
$('div#scrolly').scrollTo(0, 'slow').
The ScrollTo plugin is feature-packed and not limited to scrolling by an integer
value. You can pass in a relative value (like +=50px), a DOM element (it will scroll
the page to find that element), a selector string, a hash-value containing x and y co­
ordinates, or the keyword max, which will scroll to the end of the document. You
can scroll horizontally as well as vertically, and it also has some great options for
fine-tuning your destination. You can learn about all these options on the plugin’s
home page.9
Licensed to JamesCarlson@aol.com
Custom Scroll Bars
The client strolls over to your desk with a furrowed brow, holding a copy of the
“absolutely final” signed-off designs in his hand. “Now,” he starts, “these scroll
bars here won’t look like this, will they? I mean, they’re all gray, and stand out
badly.”
Usually you only have to be working as a web developer for a very short time before
a client asks you to replace the standard operating system scroll bars with custom
ones—especially for internal elements, like scrolling divs. It does seem like a reas­
onable request, but it has some usability implications of which you should be aware.
People have certain expectations about how core interface components of their op­
erating system will function, and custom implementations can sometimes have
different features from the core elements that they are replacing. Breaking users’
expectations in this way can be extremely frustrating, so this type of UI customization
should be undertaken with extreme care.
That said, there are times when a well-placed custom UI element can make a world
of difference to the overall feel of an interface. Ultimately, you will have to weigh
the benefits and drawbacks for your intended audience. In our case, the client is
paying—so we’ll do it!
There’s no need, however, to try and build it from scratch: a scroll bar is a complex
user interface element, and the client would be unhappy if he found out we’d wasted
9
http://flesler.blogspot.com/2007/10/jqueryscrollto.html

78 jQuery: Novice to Ninja
precious development hours building it ourselves, especially when there’s a perfectly
suitable plugin ready to go: it’s called jScrollPane.
jScrollPane is a jQuery plugin that allows you to replace the browser’s default ver­
tical scroll bars with custom ones in any element with overflowed content. You can
find the plugin in the official repository, but a more up-to-date version is available
on Google Code.10
There are two files we need to include: the JavaScript code file, jScrollPane-1.2.3.min.js;
and the accompanying CSS file, jScrollPane.css. The CSS file sets out some default
styles for the scroll bars, and gives you a starting point for implementing your own
customizations. Simply extend or overwrite the styles contained in this file with
Licensed to JamesCarlson@aol.com
your own colors and images to create your customized scroll bars. We’ll stick with
the default style for our example: a sleek-looking gray bar that will fit in on just
about any site (as illustrated in Figure 3.6).
Figure 3.6. A custom scroll bar
You can activate custom scroll bars on any element by simply calling the jScrollPane
function on it. Although parameters are optional, there are more than a dozen for
you to tweak, such as showing scroll bar arrows, or moving the scroll bars to the
left-hand side of the panel. You can see the full list on the plugin’s home page.11
For our example, we’ll set a margin between our content and the scroll bar, set the
width of the scroll bar, and choose to hide the top and bottom arrows:
chapter_03/16_custom_scrollbar/script.js (excerpt)
$('#fine_print').jScrollPane({
scrollbarWidth: 10,
scrollbarMargin: 10,
showArrows: false
});
10
http://code.google.com/p/jscrollpane/
11
http://www.kelvinluck.com/assets/jquery/jScrollPane/jScrollPane.html

Animating, Scrolling, and Resizing 79
Our new scroll bar looks and works great, but you might notice that it fails to respond
when you scroll the mouse wheel over the element. jQuery’s core library has delib­
erately left out mouse wheel functionality to keep the library’s size to a minimum,
but there’s a plugin to add it back in,12 and jScrollPane has been written with this
plugin in mind. As a result, all you need to do is include the mouse wheel plugin
in your page and jScrollPane will automatically add mouse wheel event handling
to all your scrolling content panes, letting you scroll them however you please!
Resizing
Resizing has a few different meanings in relation to a user interface: the first that
comes to mind is the ability to resize the browser window (an event that has often
Licensed to JamesCarlson@aol.com
caused headaches for web developers). But also common are resizing windows inside
applications, and resizing images or other elements.
jQuery includes a way of gathering information about user-initiated window resizing,
and also (via jQuery UI) a way to give users ultimate resizing power over any element
on the page. Let’s dive in!
The resize Event
The resize event is a core jQuery event that fires when a document view is resized.
There are a number of reasons why you’d want to react to this event. But before we
examine a practical example, let’s make sure we understand how the event works:
chapter_03/17_resize_event/script.js (excerpt)
$(window).resize(function() {
alert("You resized the window!");
});
Load the index.html page in your browser and try resizing the window: every time
you do, an alert will pop up. Annoying users every time they change their browser
window size will probably keep us from winning any user-experience points—so
let’s put this event to use in a more practical example.
12
http://plugins.jquery.com/project/mousewheel

80 jQuery: Novice to Ninja
Layout Switcher
If you’ve worked with CSS for any length of time, you’ll know that there’s a constant
debate about which is best: fluid or fixed-width layouts. On one hand, fluid layouts
make maximal use of a user’s screen real estate; on the other hand, fixed-width
layouts allow you to design a pixel-perfect layout that you know won’t break when
a user is viewing it with a different viewport size.
For StarTrackr! we can offer the best of both worlds: design two separate, fixed-
width layouts, and switch between them by catching the resize event.
Let’s start! The default StarTrackr! web site we’ve been working with so far is a
modest 650px wide. Our first task is to write some styles to make it wider—we’ll
Licensed to JamesCarlson@aol.com
go for 850px for the wider version:
chapter_03/18_layout_switcher/wide.css
body #container {
width: 850px;
}
body #container p {
width: 650px;
}
body #header {
background-image: url('../../css/images/header-corners-wide.png');
}
body #celebs table {
width: 650px;
margin-left: 5px;
}
Notice that we’ve added a seemingly superfluous body to the beginning of each rule.
This is so that these rules will take precedence over any rules in our base style sheet
targeting the same elements, because they’re more specific.
The next step is to write the jQuery code to add or remove our new style sheet. All
we need to do is test to see if the body element’s width is greater than 900px, append
the style sheet to our head element if it is, or remove it if it’s not:

Animating, Scrolling, and Resizing 81
chapter_03/18_layout_switcher/script.js (excerpt)
if ($('body').width() > 900) {
$('')
.appendTo('head');
} else {
$('link[href=wide.css]').remove();
}
This puts us in a tight spot. We need to run this code in two different situations:
once when we first load the page and then again whenever the page is resized. You
might be tempted to just copy and paste that chunk of code, and be done with it.
Licensed to JamesCarlson@aol.com
Resist that temptation! Repeating yourself in code is almost always a bad idea:
imagine a situation where, a few months down the line, you decide that 900px was
the wrong cutoff point. You’re now thinking that you should switch style sheets
only around the 1000px mark. You go into your code, change the value, and reload
the page. But it’s broken, because you forgot to change the same value in the other,
identical block of code. This kind of scenario can happen all too easily in any type
of software development, and the more complicated your code becomes, the more
likely it will happen—and the harder it will be to track down.
Fortunately, almost every programming language has constructs to help us out in
these kinds of situations, and JavaScript (and hence jQuery) is no exception. So far
we’ve been passing anonymous functions to all our event handlers, but now it’s
time to give our function a name: