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
416,85 KB
Nội dung
Licensed to JamesCarlson@aol.com 382 jQuery: Novice to Ninja When we “add” a string and a number using the + operator, JavaScript assumes we’re trying to concatenate the two, so it creates a new string. It would appear to change the number’s variable type to string. When we use the multiplication oper- ator (*) though, JavaScript assumes that we want to treat the two variables as num- bers. The variable itself remains the same throughout, it’s just treated differently. We can always explicitly tell JavaScript how we intend to treat a variable, but if we don’t, we need to understand just what JavaScript is doing for us. Here’s another example: alert(a + c);// alerts 22 alert(a + parseInt(c));// alerts 4 Equality Operators The equal sign (=) and its related operators can also provide a trap for young players. And where it was once just a little odd, it became even more so in JavaScript 1.3. The first trick is that the equal sign has a different meaning than what you remember from your school mathematics classes: var a = 2; var b = "2"; A single equal sign is an assignment operator, and is used to assign values to vari- ables. We all knew what it did, but now we know what it’s called: var c = (a == b); Two = signs together, ==, is known as the equality operator, and establishes a Boolean value. In our example, the variable c will have a value of true, as JavaScript compares the values before and after the equality operator, and considers them to be equal. Using the equality operator, JavaScript pays no heed to the variable’s type, and attempts to coerce the values to assess them. Switch out the first equal sign for an exclamation mark, and you have yourself an inequality operator (!=). This operator will return false if the variables are equal, or true if they aren’t: Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Appendix B: JavaScript Tidbits 383 var d = (a != b); The variable d will now have a value of false, since a and b are equal. It may be a little complex, but at least it’s consistent. In JavaScript 1.3, the situation became less simple still, with the introduction of one further operator: the strict equality operator, shown as ===. var e = (a === b); The strict equality operator differs from the equality operator, in that it pays strict attention to type as well as value when it assigns its Boolean. In the above case, d is set to false: while a and b both have a value of 2, they have different types. And as you might have guessed, where the inequality operator was paired with the equality operator, the strict equality operator has a corresponding strict inequality operator: var f = (a !== b); In this case the variable f will return true, as we know the two compared variables are of different types, though similar values. Suffice it to say that some equal signs are more equal then others! Truthiness and Falsiness JavaScript’s Boolean type has two possible values—true and false: var jQueryIsFun = true; var javaScriptIsJava = false; But we know that JavaScript likes to be trickier than this. In reality, there are a multitude of ways that variables can evaluate to true or false. These values are referred to as being truthy or falsy. So when we write if(variable) { … }, variable need not be a Boolean value: the code between the brackets will run if variable contains the number 5, or the string "Hello World!", or even an empty array. Any Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com 384 jQuery: Novice to Ninja value that acts as though it were the Boolean value true in this type of context is called truthy, and any value that acts like false is called falsy. JavaScript treats all these values as truthy: ■ true ■ 1 (because it’s a non-zero number) ■ "0" (because it’s a non-empty string) ■ "false" (because it’s a non-empty string) ■ function() {} (any function) ■ {} (any object) ■ [] (any array) And these values are falsy: ■ false ■ 0 (the number zero) ■ "" (an empty string) ■ null ■ undefined ■ NaN (a special number value meaning Not a Number) These values can be combined with the logical NOT operator to great effect. A single exclamation mark is used: var a = 0; var b = 1; if (!b) { // do something } else if (!a) { // do something else } The logical NOT operator returns true if the value of the variable is false and, conversely, it will return false if the value is true. In the example above, b is truthy and so !b returns false, and a is falsy so !a returns true—so the code in the else if block would execute. Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Appendix B: JavaScript Tidbits 385 It’s important to remember that while a value may be == true, it may only be truthy, and not strictly true: var a = true; var b = 1; alert(a == b);// alerts true alert(a === b);// alerts false alert(a != b); // alerts false alert(a !== b); // alerts true If you have the option, always elect to use the Boolean values of true and false. If there’s one thing that’s undoubtedly true, it’s that hunting down a truthy or falsy logic error is truly painstaking! Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Appendix C: Plugin Helpers There are a few jQuery properties and actions that, although applying to any jQuery selection, are particularly useful for plugin development. The reason they’re hidden away in this appendix is that they’re uncommonly used. Despite this, they’re quite powerful, and you should familiarize yourself with them if you intend to spend time developing plugins. Selector and Context The first ones we’ll look at are the selector and context properties. These work together to show you what jQuery thinks it’s working on. The selector property returns a string value of the current jQuery selector string: so the command $('p:first').selector will return the string "p:first". This is useful in your plugins if you need to know what the user originally selected. You might think that the optional second parameter to the jQuery selector, which is called context, is what you’d obtain with the context property—but it’s a bit trickier than that. In fact, if you supply context as a string, it’s converted internally to a regular jQuery statement, which will actually affect the selector property: var selector = $('p:first', '#content').selector var context = $('p:first', '#content').context In the above example, the selector resolves to "#content p:first" and the context resolves to Document (the context that all your selectors will default to). The context property is only modified if you supply an actual DOM node to it: var domContext = $('#content')[0]; // Get the DOM element var selector = $('p:first', domContext).selector; var context = $('p:first', domContext).context; In this case, the selector will be reported as "p:first", and the context will be the DOM element itself (for this example, it’s the <div id="content"> element). Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com 388 jQuery: Novice to Ninja Specifying the DOM node provides no guarantee that your queries will run faster; internally jQuery’s selector engine will only search inside the context you specify anyway, even though the context property will be reported as Document. The jQuery Stack To make our plugins play nicely with jQuery, we’ve learned that we should return each jQuery element from our code, so that commands can continue to be chained after our plugin. Generally, we just modify elements in the selection before we pass them back, but sometimes we want to alter the items that are returned—perhaps remove some elements, or add some new ones. The best way to accomplish this is via the pushStack action. This is a convenient way to create a jQuery selection for inclusion in the chain. By way of example, we’ll set up a small plugin that retrieves the elements that sur- round the selected element. The use case might be to highlight the next and previous items in a list of elements. Our plugin will also wrap around if the selected item is the first or last in the list: jQuery.fn.surrounds = function() { var prev = this.index() == 0 ? this.siblings(':last') : this.prev(); var next = this.index() == this.siblings().length ? this.siblings(':first') : this.next(); var newStack = prev.add(next); return this.pushStack(newStack, 'surrounds', ''); }; The plugin retrieves the previous and next elements, and combines them into one selection with the add action. This new collection is returned via pushStack, which accepts the collection, a name for it, and a name for the selector string. The two name parameters will be readable by the selector property we looked at above. To use this plugin, we might apply it to an unordered list called categories, like so: Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Appendix C: Plugin Helpers 389 $('#categories li:first') .surrounds() .css('color', 'red') .end() .css('color', 'blue'); This will select the two elements that surround the first list item, then color them red. Because we’ve used pushStack, the jQuery chain remains intact; we can then use the end command to move back to the original selection (the first list item), and color it blue. You can use pushStack anytime you want to manipulate the chain like this. The last trick we’ll look at in regard to the jQuery internal chain is the ability to access other steps in the chain. As you might remember, the end action takes you back up one level to the last command that modified the jQuery selection. If you look into the jQuery core, you’ll see that end is implemented using the prevObject property. Inside your plugin you can gain access to the previous jQuery object by using this.prevObject. If the previous object has a previous object, you can access this too! Minification You know there are two versions of jQuery, jQuery UI, and many jQuery plugins: an uncompressed version and a minified version. Why is this so? Regardless of which one you choose, when you add them to your page you gain access to all the features of jQuery (or the plugin in question). The difference is, of course, that the file size of the “.min” version is markedly smaller. With jQuery 1.3.2 coming in at around 118KB and the minified version at 55.9KB, you save over half the file size in bandwidth. And if the file is half as big, it’s delivered twice as fast. Faster downloads mean faster pageloads, so you may be wondering how to enjoy the benefit of minified files with your own script files, and—more importantly—your plugins. There are a number of utilities you can use to compress your files, so we’ll go over a few of the more commonly used ones. Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com 390 jQuery: Novice to Ninja Douglas Crockford’s JSMin 1 was first released in December of 2003, and currently comes in both the original executable version (along with the C source code), as well as a host of other language options: C#, Java, JavaScript, Perl, PHP, Python, OCaml, and Ruby. Of a similar pedigree, but slightly more accessible to use, is Dean Edwards’ Packer. 2 It’s primarily accessed via a web page interface, but it also has .NET, Perl, and PHP applications available for download. Both solutions work by eliminating whitespace—line breaks and extraneous spaces—and by shortening variable and function names. The code becomes obfus- cated by human standards, but the browser’s JavaScript engine has no trouble inter- preting the code output. So, for example, this human-readable code: $growl.animate({ border: "none", height: 0, marginBottom: 0, marginTop: "-6px", opacity : 0, paddingBottom: 0, paddingTop: 0, queue: false } … would be shortened to this: $growl.animate({border:"none",height:0,marginBottom:0,marginTop: ➥"-6px",opacity :0,paddingBottom:0,paddingTop:0,queue:false} The second statement has the whitespace removed, and you can already see that it’s taking up less space to achieve the same results. You can also see how it’s become more difficult to read. Multiply this effect by the 4,377 lines in the jQuery source, and you can imagine how difficult it would be to make any sense of it. And that’s without altering any names. 1 http://www.crockford.com/javascript/jsmin.html 2 http://dean.edwards.name/packer/ Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Appendix C: Plugin Helpers 391 Of these two methods, Packer is arguably the more extensive, not only removing whitespace but also converting names to base 62. Its compressed footprint can therefore be smaller, yet this mightn’t necessarily result in the fastest solution, as it means the minified code must be “unpacked” when delivered to the browser. Edwards’ most recent modifications have seen some astounding increases in unpack- ing speeds, but this overhead should be considered when adopting a final solution. Two other popular options for minifying your JavaScript are Yahoo’s YUI Com- pressor 3 and Google’s Closure Compiler. 4 The teams behind all four methods—well, three, as Crockford is fairly much sorted with JSMin—are continually refining their solutions, and are responsive to industry and community feedback. 3 http://developer.yahoo.com/yui/compressor/ 4 http://code.google.com/closure/compiler/ Licensed to JamesCarlson@aol.com [...]... operator, 177 ' (quotes), 28, 282 + arithmetic operator, 158 ++ increment operator, 115, 222 (dot) notation, 130 (period), namespaces, 356 1-up notifications, 287–290 :checked filter, 233 :eq filter, 125 :eq selector attribute, 106 :even filter, 24 :hover pseudo selector, 144 :not selector, 151 :selected filter, 233 = (assignment) operator, 382 == (equality) operator, 382 === (strict quality) operator,... 223 adding to plugins, 339–342 JavaScript, 182–192 effects, 44 map objects, 183 number of, 46 namespaces, 184 passing, 290 scope, 186 running, 340 color animation, 53 success callback, 209 ColorBox plugin, 98 attributes :eq selector attribute, 106 title attribute (links), 169 autocomplete, forms, 248 axis option (draggable interaction help er), 267 Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com... anonymous functions, 44 API (Application Programming Inter face), fetching data, 200 appending lists, 315 arithmetic (+) operator, 158 assignment (=) operator, 382 async Ajax option, 373 Asynchronous JavaScript and XML (see Ajax) attr action, 95, 304 attribute selectors, 75 Licensed to JamesCarlson@aol.com enableSelection action, 273 filter action, 304 hide action, 32 html action, 41 is action, 35 live... 382 === (strict quality) operator, 383 394 Licensed to JamesCarlson@aol.com ajaxComplete global events, 207 ajaxError global events, 206 ajaxSend global events, 207 ajaxStart global events, 207 ajaxStart method, 215 ajaxStop global events, 207 ajaxStop method, 215 ajaxSuccess global events, 207 aliases event parameters, 133 using, 11 and (&&) operator, 177 animated navigation, 64–69 animating, 51–72... plugin, 283 shift-selecting checkboxes, 330 bind action, 247 child elements, defined, 13 bind method, 360 child selectors, styling top-level links, binding multiple events, 247 138 binding, iPhones, 357 classes Boolean type, JavaScript, 383 decorating, 29 boxModel property ($.support method), toggleClass method, 309 377 clearInterval command, 109 browser sniffing, 191 clearTimeout command, 109 browsers...Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com Index Symbols Licensed to JamesCarlson@aol.com A “above the fold”, defined, 348 accessibility, semi-transparent controls, 167 action attr, 95 actions $.ajaxSetup action, 203 about, 12,... animating CSS properties, 52 child selectors, 138 CSS3 selectors, 3 IE6, 179 layout switcher, 80 properties, 25–28 tabs, 157 z-index property, 112 cssFloat property ($.support method), 377 Cycle plugin, 117 D data accessing with selectables, 297 fetching with $.getJSON, 200 sending form data, 227–229 data action, 125, 126, 366 data Ajax setting, 374 Licensed to JamesCarlson@aol.com columns, selecting... 35 live action, 280 one action, 336 parent actions, 121 pushStack action, 388 remove action, 40 text action, 41, 305 add method, 151 addClass function, 30 adding callbacks to plugins, 339–342 classes, 30 elements, 37–40 options to plugins, 337 Ajax (Asynchronous JavaScript and XML), 193–207 $.ajax method, 202 about, 193 client-side Twitter searcher, 201 events, 206 fetching data with $.getJSON, 200... 12, 33 attr action, 304 bind, 247 chaining actions, 62 closest action, 287 data action, 125, 126, 366 default event actions, 140 delay, 63 disableSelection action, 273 Licensed to JamesCarlson@aol.com !== (strict inequality) operator, 383 # (hash symbol) id name, 21 $ (dollar sign) JavaScript variable name, 12 uniqueness of, 362 $(document).ready() function, 18, 27 $ prefixed functions, 345 $.active property... selector attribute, 106 title attribute (links), 169 autocomplete, forms, 248 axis option (draggable interaction help er), 267 Licensed to JamesCarlson@aol.com Licensed to JamesCarlson@aol.com 396 Licensed to JamesCarlson@aol.com date picker, 257–260 drag and drop, 264–271 navigation, 136 navigation controls in plugins, 321 progress bar, 274 sliders, 260–264 sortable behavior, 271 tabs, 161 create method, . Licensed to JamesCarlson@aol.com 382 jQuery: Novice to Ninja When we “add” a string and a number using the + operator, JavaScript assumes we’re trying to concatenate the two,. after the equality operator, and considers them to be equal. Using the equality operator, JavaScript pays no heed to the variable’s type, and attempts to coerce the values to assess them. Switch. operator, and is used to assign values to vari- ables. We all knew what it did, but now we know what it’s called: var c = (a == b); Two = signs together, ==, is known as the equality operator,