Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 15 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
15
Dung lượng
920,97 KB
Nội dung
Licensed to JamesCarlson@aol.com 82 jQuery: Novice to Ninja chapter_03/18_layout_switcher/script.js (excerpt) $(document).ready(function() { stylesheetToggle(); $(window).resize(stylesheetToggle ); }); function stylesheetToggle() { if ($('body').width() > 900) { $('<link rel="stylesheet" href="wide.css" type="text/css" />') .appendTo('head'); } else { $('link[href=wide.css]').remove(); } } We’ve named our function stylesheetToggle, and called it twice: once when the document first loads, and again whenever we resize. You’ll notice that we only need to pass the function’s name to the resize event handler; since we are not de- claring a function here, we have no need for the the function keyword, or any curly braces or parentheses. Resizable Elements The jQuery UI library contains a Resizable plugin as part of its interaction function- ality. The Resizable plugin makes elements that you select able to be resized by adding a small handle to the bottom corner of the element. This can be stretched around with the mouse (much like your operating system’s windows). Like all jQuery UI components, it’s highly configurable and easy to use. If you downloaded the full jQuery UI library earlier, you’ll already have the class ready to go. Otherwise, you’ll need to head back to the download builder and include the Resizable com- ponent—which will also require the core library and a theme. Using the Resizable component in its most basic form is very easy. We simply select the element or elements we want to modify, and call the resizable function: chapter_03/19_resizable_elements/script.js (excerpt) $('p').resizable(); Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Animating, Scrolling, and Resizing 83 If we run this on our StarTrackr! site, we’re in for some unusual results: every paragraph element instantly becomes resizable! It’s a lot of fun to see this in action: suddenly our whole web page becomes malleable. By default, the Resizable interaction adds small handles in the bottom-right corners of the elements. These are styled in the jQuery UI style sheet, so have a look in there if you’re interested in changing the way they look. The default handles are illustrated in Figure 3.7. Figure 3.7. Resizable paragraphs Now let’s look at a simple situation where this functionality is very handy: resizing textarea elements. Resizable textarea Sometimes providing a usable interface can conflict with the desire to keep a design balanced and beautiful. But thanks to jQuery, we can have our cake and eat it too—and justify our way through those tricky client walk-throughs. One area where form and function often clash is in HTML form design. This is partly because users to your site will often have wildly different requirements. For example, if you’re providing an area for feedback, users will either want to write nothing, a little, or a lot. To strike a balance you could start a small textarea, but make it resizable. Therefore, the users with a lot to say will feel as if you’re letting them say it. Here’s how we can go about doing this using jQuery UI’s Resizable functionality: Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com 84 jQuery: Novice to Ninja chapter_03/20_resizable_textarea/script.js (excerpt) $('textarea').resizable({ grid : [20, 20], minWidth : 153, minHeight : 30, maxHeight : 220, containment: 'parent' }); This makes all our textarea elements resizeable, just like we did with the paragraph elements. The effect is shown in Figure 3.8. However, we’ve specified a few new parameters to improve the feel, and to show the Resizable component’s flexibility. It has a plethora of configuration options, which you can explore in more detail on the jQuery UI documentation site. 13 Figure 3.8. Resizable textarea We’ve also constrained how far the element can be stretched by specifying the minHeight, minWidth, and maxHeight properties. You’ll notice that we’ve omitted the maxWidth property in favor of the containment parameter: this lets you specify a container restricting the resizable element. You can use either a jQuery selector as the parameter or the special keyword parent to refer to the resizable element’s parent element. We’ve also used the grid option to confine the resizable object to steps of a certain size. For some reason, this seems to add a nice feel to the resizing interaction. The 13 http://docs.jquery.com/UI/API/1.7/Resizable Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Animating, Scrolling, and Resizing 85 grid is specified as an array containing two elements: the horizontal grid size and the vertical grid size. One other parameter you’ll want to look into is the handles parameter. This specifies which sides of the element the handles will be attached to and, consequently, in which directions the element can be stretched. The parameter accepts the following options: n, e, s, w, ne, se, sw, nw, and all. You can specify any number of these by separating them with a comma. For example, { handles : 'n', 'se'} adds handles to the top and bottom-right of the element. It’s common to see this kind of functionality built into input pages where content length will vary significantly. Pane Splitter Despite the disclaimer message functionality we’ve provided, our client’s legal team is still worried about the possible repercussions that might extend from failing to properly outline the company’s terms and conditions. The problem, from a design and usability perspective, is that there are pages and pages of terms and conditions divided into many subsections—yet they need to be prominently displayed on the home page. Perhaps a splitter could help us out. A splitter is a UI component that divides multiple areas on a page in a way that al- lows users to resize elements; this way, users are able to decide how much space they want to allot each area. Splitters are commonplace in desktop applications, and with the explosion of Rich Internet Applications, they’re making their way onto the Web. We can build on our experience with the Resizable component to simulate a simple splitter that contains a “Table of Contents” in one pane and StarTrackr!’s “Terms and Conditions” content in the other. The widget’s appearance is shown in Figure 3.9. Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com 86 jQuery: Novice to Ninja Figure 3.9. A horizontal pane splitter For now we’ll focus solely on the resizing functionality. Dynamically loading each section’s content into the panes will be covered in plenty of detail in Chapter 5. Our splitter will consist of two div elements, representing each pane, nested inside of a containing element that has fixed dimensions. We’ll encase the table of contents in a block-level element, so that when the user resizes the panes the text won’t wrap and mess up our nested list: chapter_03/21_horizontal_pane_splitter/index.html (excerpt) <div id="splitter"> <div class="pane" id="tocPane"> <div class="inner"> ⋮ </div> </div> <div class="pane" id="contentPane"> <div class="inner"> ⋮ </div> </div> </div> We’ll now add some simple styles in a new splitter.css style sheet. You can see that we’ve fixed the height of the containing div, and made the child elements each consume 50% of the width by default. You could change this to specify different values if it was necessary to start with an alternative to a 50:50 split. If you need to use a CSS border, you’ll have to specify your widths in pixels and make sure they all add up: Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Animating, Scrolling, and Resizing 87 chapter_03/21_horizontal_pane_splitter/splitter.css #splitter { height: 150px; margin-top: 30px; margin-bottom: 50px; } #splitter .pane { width: 50%; height: 100%; float: left; } #splitter h2 { margin-bottom: 0; padding-bottom: 0; } #tocPane { overflow: hidden; background: #d6dde5 url( /images/handle.png) no-repeat ➥right center; } #tocPane .inner { width: 300px; } #contentPane { overflow: auto; } #contentPane .inner { padding: 0 5px; } Next, our jQuery code. To create a horizontal splitter, we make the first element resizable and specify an east-facing handle—so only the right edge of the div will be resizable. If you were to run the example with only a simple resizable statement, you’d notice that we’re almost there: the two elements act somewhat like a split pane—except that the right element’s width remains constant rather than expanding to fill the Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com 88 jQuery: Novice to Ninja remaining space when you drag the handle. To take care of that, we’re going to have to do some calculations inside the resizable widget’s resize function. This is an event handler that fires as the component is being resized: chapter_03/21_horizontal_pane_splitter/script.js (excerpt) $('#splitter > div:first').resizable({ handles: 'e', minWidth: '100', maxWidth: '400', resize: function() { var remainingSpace = $(this).parent().width() - ➥$(this).outerWidth(); var divTwo = $(this).next(); var divTwoWidth = remainingSpace - (divTwo.outerWidth() - ➥divTwo.width()); divTwo.css('width', divTwoWidth + 'px'); } }); Every resizing will now also trigger a change in the second element’s width. A bit of basic math helps us work out what the widths should be: we take the parent container’s width (that is, the total width), then subtract the first div’s outerWidth. The outerWidth function is a useful way to grab the total width of an element, in- cluding any padding and borders (it can also include margins if you pass it the op- tional parameter true). Perhaps unsurprisingly, there’ s a corresponding outerHeight function as well. Having calculated how much space is left to use up, we’re almost ready to set the first element’s width. There’s just one remaining catch: if the second div has borders or padding, we need to take these into consideration. Unfortunately the outerWidth function is read-only, so we’re unable to use it to set the total height. To calculate how much of the element’s width consists of borders and padding, we need to subtract the element’s outerWidth from its width. Subtracting that from the remainingSpace variable gives us exactly how many pixels wide the second div needs to be—and we can complete our horizontal splitter. Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Animating, Scrolling, and Resizing 89 JavaScript Variables The line var remainingSpace = $(this).parent().width() - $(this).outerWidth(); assigns the result of the calculation to a variable called remainingSpace. From now on in our code, we can simply write remainingSpace whenever we need to access this value. The following line (var divTwo = $(this).next();) is performing a very similar function, except that this time we’re assigning a jQuery selection to a variable (divTwo). This can subsequently be used like any other jQuery selection. Using variables like this helps to make your code more readable, as you can keep each line as concise as possible. It also makes your code more efficient; retrieving a value from a variable is much quicker for JavaScript than figuring out the value in the first place. If we then wanted to have a go at implementing a vertical splitter, there’s little to change: our pane elements stack on top of each other (rather than side by side), and our resizable call uses a south-facing handle instead of an east-facing one. The code is also almost identical—but now we’re interested in the element’s heights, not widths: chapter_03/22_vertical_pane_splitter/script.js (excerpt) $('#splitter > div:first').resizable({ handles: 's', minHeight: '50', maxHeight: '200', resize: function() { var remainingSpace = $(this).parent().height() - ➥$(this).outerHeight(); var divTwo = $(this).next(); var divTwoHeight = remainingSpace - ➥(divTwo.outerHeight() - divTwo.height()); divTwo.css('height', divTwoHeight + 'px'); } }); These simple splitters are quite useful, require very little code, and will be suitable for many purposes. But if you require complex splitter behavior, such as multiple split panes or nested panes, head over to the plugin repository and check out the jQuery Splitter plugin. Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com 90 jQuery: Novice to Ninja That’s How We Scroll. And Animate. What a chapter! We’ve mastered animation, scrolling, and resizing, and seen how chaining can help us easily write succinct, powerful functionality in a readable and natural manner. We’re starting to apply our jQuery knowledge to create some great effects. However, what’s important to concentrate on as you move through the book is not the effects themselves, but the underlying concepts that we use to implement them. Even the most complex-looking effects tend to come out of a few simple actions chained together cleverly. It’s up to you to sit down, think up some ideas, and try to implement them for yourself. Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Chapter 4 Images and Slideshows There’s no more fooling around now. With the basics well and truly under our belts, we already have unlimited potential to create some world-class effects. Our client is over the moon; we’ve given him his “Web 2.0,” and now his questionable startup has found favor with several of the big social networking sites. He’s asked us to add in some “stuff” that really cooks: “image galleries, slideshows, fading effects—the works!” And why not? We have the tools, and we have the talent! It would be a fairly boring Internet (at least visually) without images; much of the content we receive on our web-based travels is in the form of pictures and design elements such as borders, icons, and gradients that help to define our interaction with a web page. When we combine all of these elements with a healthy dose of jQuery, we start to see some vibrant and startling effects emerge. As well as the bog- standard components we’ve come to know and love, jQuery provides the means for implementing some less common, relatively new effects and features that would be difficult to do in JavaScript alone. Licensed to JamesCarlson@aol.com [...]... settings you want the new item to have For example: 96 jQuery: Novice to Ninja chapter_04/01_lightbox/script.js (excerpt) function positionLightboxImage() { var top = ($(window).height() - $('#lightbox').height()) / 2; var left = ($(window).width() - $('#lightbox').width()) / 2; $('#lightbox') css({ 'top': top + $(document).scrollTop(), 'left': left }) fadeIn(); } The last task left to do is remove the lightbox... removeLightbox(); }) appendTo('#lightbox'); return false; }); The overlay is positioned at the top of the screen, and quickly faded from invisible to 50% opacity to provide the background effect The lightbox container is added to the page and immediately hidden, awaiting the loading of our image The image is added to the container, and its src attribute is set to the location of the image Licensed to JamesCarlson@aol.com... example, but is helpful when you want to extend the lightbox’s functionality, such as adding borders, descriptions, or Next and Previous buttons: chapter_04/01_lightbox/script.js (excerpt) $('') css('top', $(document).scrollTop()) css('opacity', '0') animate({'opacity': '0.5'}, 'slow') appendTo('body'); $('') hide() appendTo('body'); $('') attr('src',...92 jQuery: Novice to Ninja Lightboxes Our client wants Web 2.0, so let’s give him the quintessential Web 2.0 effect: the lightbox A lightbox—a term borrowed from photography—is used is to display fullsized versions of an image thumbnail in a modal dialog Typically, the entire background becomes darker to indicate that it’s been disabled The user must interact with the image (by hitting a close button,... screen to go dark How do we do this? The easiest way is to add a large div to the page that’s as tall and wide as the screen itself Inside that div, we’ll add another div into which we’ll load the image Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Lightboxes are very common these days, and many feature some very complex functionality: animations, transitions, as well as the ability to. .. return false; to prevent the default behavior of the HTML link from occurring Otherwise, the user would navigate away from our page and to the image itself Now let’s have a look at the positionLightbox function: Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Creating new elements is very satisfying, and a task you’ll have to do frequently There’s an alternative way to set up a new... left:0; height:100%; width:100%; background:black url(loader.gif) no-repeat scroll center center; } Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Figure 4.1 Our lightbox effect 93 94 jQuery: Novice to Ninja #lightbox_container { position:absolute; } Next, we add a click handler to our lightbox links When they’re clicked, we’ll add the dark overlay element, the image container, and the... attribute to the value provided Then we attach a few event handlers to the image One of these events is new to us: load It’s a close cousin to the ready event, but fires when an element (in this case our image) is 100% loaded Quick Element Construction $('', { src: $(this).attr('href'), load: function() { positionLightboxImage(); }, click: function() { removeLightbox(); } }).appendTo('#lightbox');... shadowy appearance One other trick is to add a spinning loader image to the center of this element When we start loading the image the spinner will display as part of the background It will appear to vanish when the image loads, but in reality it will simply be hidden behind the image: chapter_04/01_lightbox/lightbox.css #lightbox_overlay { position:absolute; top:0; left:0; height:100%; width:100%;... come up with improvements and customizations Even though plugins may be plentiful, sometimes building them yourself is more satisfying! Troubleshooting with console.log If you’ve had a go at extending or customizing this simple lightbox (or, for that matter, any of the code we’ve seen so far), you’ll no doubt have encountered a Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com When the . expanding to fill the Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com 88 jQuery: Novice to Ninja remaining space when you drag the handle. To take care of that, we’re going to have. Licensed to JamesCarlson@aol.com 82 jQuery: Novice to Ninja chapter_03/18_layout_switcher/script.js (excerpt) $(document).ready(function() { stylesheetToggle(); $(window).resize(stylesheetToggle );. nested panes, head over to the plugin repository and check out the jQuery Splitter plugin. Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com 90 jQuery: Novice to Ninja That’s How