Permalink
Browse files

Merge branch 'master' into fix_method_refs

* master: (21 commits)
  0.2.7
  Remove remaining trailing whitespace from all pages. Fixes #313.
  Style and typography fixes, and code style adherence in the JavaScript 101 section. Fixes #312.
  0.2.6
  Correct comment in :input selector in Selecting Elements article. Fixes #306.
  Expand the JavaScript 101 'Scope' article with more useful information and explanations. Fixes #201.
  Added 0 to the list of falsy values in JavaScript 101 Conditional Code article. Fixes #300. Fixes #271
  Inserted missing word in the JavaScript 101 Arrays article. Fixes #299.
  Fixed inconsistency in showLinkLocation example in Basic Plugin Creation article. Fixes #307.
  Fix example and other style cleanup in Basic Plugin Creation article. Fixes #310. Fixes #311.
  Update list of reserved words in JavaScript. Fixes #301.
  Style and typography fixes and code style adherence in the Events section. Fixes #294.
  Style and typography fixes, and code style adherence in the Effects section. Fixes #290.
  Style and typography fixes, and code style adherence in the Code Organization section. Fixes #287.
  Remove double ampersands in README header. Fixes #284.
  Code and prose style improvements to all articles in Ajax chapter. Fixes #283.
  Style fixes on the About page. Fixes #279.
  Style guide fixes for the index, contributing, and About jQuery articles. Fixes #270
  relabel queue/dequeue content as advanced
  Added a missing 'i' in the for loop. Fixes #280.
  ...

Conflicts:
	page/ajax/ajax-and-forms.md
	page/ajax/jquery-ajax-methods.md
	page/effects/custom-effects.md
	page/effects/intro-to-effects.md
	page/events/event-basics.md
	page/events/event-helpers.md
	page/events/introduction-to-custom-events.md
	page/events/triggering-event-handlers.md
  • Loading branch information...
2 parents 19d5d88 + 2d88c58 commit bac5e33de7123ea904ea1342bc0fbb1c095b5dda @rmurphey committed Mar 17, 2013
Showing with 2,081 additions and 2,370 deletions.
  1. +8 −8 CONTRIBUTING.md
  2. +1 −1 README.md
  3. +1 −1 package.json
  4. +7 −7 page/about-jquery/additional-support.md
  5. +64 −64 page/about-jquery/how-jquery-works.md
  6. +8 −8 page/about.md
  7. +5 −5 page/ajax.md
  8. +36 −57 page/ajax/ajax-and-forms.md
  9. +9 −14 page/ajax/ajax-events.md
  10. +59 −76 page/ajax/jquery-ajax-methods.md
  11. +25 −30 page/ajax/key-concepts.md
  12. +17 −21 page/ajax/working-with-jsonp.md
  13. +18 −29 page/code-organization/beware-anonymous-functions.md
  14. +143 −163 page/code-organization/concepts.md
  15. +29 −29 page/code-organization/deferreds.md
  16. +159 −161 page/code-organization/deferreds/examples.md
  17. +39 −40 page/code-organization/deferreds/jquery-deferreds.md
  18. +10 −20 page/code-organization/dont-repeat-yourself.md
  19. +18 −26 page/code-organization/feature-browser-detection.md
  20. +2 −2 page/effects.md
  21. +18 −22 page/effects/custom-effects.md
  22. +52 −53 page/effects/intro-to-effects.md
  23. +28 −37 page/effects/queue-and-dequeue-explained.md
  24. +144 −182 page/effects/uses-of-queue-and-dequeue.md
  25. +2 −2 page/events.md
  26. +65 −65 page/events/event-basics.md
  27. +34 −49 page/events/event-delegation.md
  28. +69 −75 page/events/event-extensions.md
  29. +9 −13 page/events/event-helpers.md
  30. +46 −47 page/events/handling-events.md
  31. +40 −39 page/events/history-of-events.md
  32. +11 −17 page/events/inside-event-handling-function.md
  33. +235 −275 page/events/introduction-to-custom-events.md
  34. +45 −61 page/events/introduction-to-events.md
  35. +19 −27 page/events/triggering-event-handlers.md
  36. +17 −19 page/index.html
  37. +3 −2 page/javascript-101.md
  38. +35 −34 page/javascript-101/arrays.md
  39. +59 −83 page/javascript-101/closures.md
  40. +37 −47 page/javascript-101/conditional-code.md
  41. +32 −40 page/javascript-101/functions.md
  42. +38 −33 page/javascript-101/getting-started.md
  43. +30 −48 page/javascript-101/loops.md
  44. +11 −11 page/javascript-101/objects.md
  45. +11 −16 page/javascript-101/operators.md
  46. +7 −18 page/javascript-101/reserved-words.md
  47. +21 −31 page/javascript-101/running-code.md
  48. +131 −50 page/javascript-101/scope.md
  49. +9 −11 page/javascript-101/syntax-basics.md
  50. +9 −11 page/javascript-101/testing-type.md
  51. +27 −27 page/javascript-101/this-keyword.md
  52. +38 −53 page/javascript-101/types.md
  53. +21 −21 page/jquery-mobile/getting-started.md
  54. +23 −23 page/jquery-mobile/theme-roller.md
  55. +6 −6 page/jquery-ui/getting-started.md
  56. +2 −2 page/jquery-ui/theming.md
  57. +1 −1 page/jquery-ui/theming/themeroller.md
  58. +1 −1 page/jquery-ui/widget-factory/how-to-use-the-widget-factory.md
  59. +3 −3 page/jquery-ui/widget-factory/why-use-the-widget-factory.md
  60. +1 −1 page/performance/append-outside-loop.md
  61. +1 −1 page/performance/cache-loop-length.md
  62. +1 −1 page/performance/dont-act-on-absent-elements.md
  63. +1 −1 page/performance/read-the-source.md
  64. +14 −35 page/plugins/basic-plugin-creation.md
  65. +3 −3 page/plugins/finding-evaluating-plugins.md
  66. +1 −1 page/plugins/stateful-plugins-with-widget-factory.md
  67. +7 −7 page/style-guide.md
  68. +1 −1 page/using-jquery-core/iterating.md
  69. +1 −1 page/using-jquery-core/selecting-elements.md
  70. +3 −1 page/using-jquery-core/understanding-index.md
View
16 CONTRIBUTING.md
@@ -1,13 +1,13 @@
---
title: Contributing
-customFields:
+customFields:
-
key: "is_chapter"
value: 0
---
Depending on your level of experience with some of the workflows common to many
-open source projects, e.g., git/Github, the command line, and setting up a
+open source projects, e.g. git/GitHub, the command line, and setting up a
local development environment, contributing to this site may be a breeze or
come with a bit of a learning curve. If you fit into the former group, great!
Jump ahead to learn how to get started.
@@ -38,7 +38,7 @@ you are probably familiar with the frustrating feeling of putting a useful tip
out there, and then wondering if it's actually making its way to the people who
need it, and what to do with that old post years and versions down the road.
You're invited to share that energy to help us bring that ecosystem together
-and grow it further!
+and grow it further!
If you've ever helped anyone, colleague or stranger, with a particular problem,
then you know the value of having a reference you can quickly link to that says
@@ -71,7 +71,7 @@ controls most of the layout for all of our sites, and there is a [child
theme](https://github.com/jquery/jquery-wp-content/tree/master/themes/learn.jquery.com)
that controls the templates and styles specific to the learn site.
-[`jquery-wp-content`](http://github.com/jquery/jquery-wp-content) powers our sites in
+[`jquery-wp-content`](http://github.com/jquery/jquery-wp-content) powers our sites in
production and staging environments, and can set up for local development relatively easily.
### Build
@@ -80,7 +80,7 @@ The static content in the `page` directory is deployed to a
[`jquery-wp-content`](http://github.com/jquery/jquery-wp-content) instance
using [grunt](http://gruntjs.com), specifically with two grunt plugins we've created:
-* [grunt-jquery-content](http://github.com/jquery/grunt-jquery-content) - pre-processes content in a variety of formats (HTML, Markdown, XML) into HTML, applying syntax highlighting and some simple partial support, preparing it for processing by
+* [grunt-jquery-content](http://github.com/jquery/grunt-jquery-content) - pre-processes content in a variety of formats (HTML, Markdown, XML) into HTML, applying syntax highlighting and some simple partial support, preparing it for processing by
* [grunt-wordpress](http://github.com/scottgonzalez/grunt-wordpress) - syncs static content to WordPress using [XML-RPC](http://codex.wordpress.org/XML-RPC_Support)
@@ -129,7 +129,7 @@ Once you've gotten your environment working, here are the general steps you shou
1. Create a new "feature" branch based on `master` -- `git branch <feature/issue name/number>`
2. Move onto that branch -- `git checkout <feature/issue name/number>`
-3. Work on your awesome contribution.
+3. Work on your awesome contribution.
4. As you work and want to preview your changes, use `grunt` to deploy them to the your site. You can also use `grunt watch` to have the site monitor the `page` directory for any changes and automatically have the changes deployed every time you save.
5. When you're done, stage the new/modified preparation for commit -- `git add page/faq/how-do-i-add-a-new-article-to-the-learn-site.md`
6. Commit the files to your local repo -- `git commit -m "add a relevant message describing the change"`
@@ -142,10 +142,10 @@ Requests](http://contribute.jquery.org/commits-and-pull-requests/) guide.
### Adding A New Article
-1. Add the file to the right folder in the page folder.
+1. Add the file to the right folder in the page folder.
2. Add the slug name (the filename without the extension) to the desired location `order.yml`
3. Run `grunt`
-4. You should now be able to navigate to the file.
+4. You should now be able to navigate to the file.
### Formatting Articles
View
2 README.md
@@ -36,7 +36,7 @@ Each of the articles on the site has some [YAML "Front Matter"](https://github.c
`level: advanced`
-## Building && Working Locally
+## Building & Working Locally
As this site is part of the jQuery network of sites, its presentation is controlled by our [web base template](https://github.com/jquery/jquery-wp-content). To preview the site locally, first follow the [instructions there](https://github.com/jquery/jquery-wp-content) to set up a local version of the jQuery WordPress network. Then, clone this repo and run the following steps (node.js required).
View
2 package.json
@@ -2,7 +2,7 @@
"name": "learn.jquery.com",
"title": "jQuery Learning Site",
"description": "jQuery Foundation site for learning jQuery and JavaScript",
- "version": "0.2.5",
+ "version": "0.2.7",
"homepage": "http://learn.jquery.com",
"author": {
"name": "jQuery Foundation (http://jquery.org/)"
View
14 page/about-jquery/additional-support.md
@@ -27,7 +27,7 @@ There are many subforums where you can discuss jQuery, ask questions, talk about
* [Developing jQuery Plugins](http://forum.jquery.com/developing-jquery-plugins)
* This forum covers development of jQuery plugins.
* [Developing jQuery UI](http://forum.jquery.com/developing-jquery-ui)
- * This is the place to discuss development of [jQuery UI](http://jqueryui.com/) itself - including bugs, new plugins, and how you can help.
+ * This is the place to discuss development of [jQuery UI](http://jqueryui.com/) itself including bugs, new plugins, and how you can help.
* All jQuery UI svn commits are posted to this list to facilitate feedback, discussion, and review.
* Also note that a lot of the development and planning of jQuery UI takes place on the [jQuery UI Development and Planning Wiki](http://wiki.jqueryui.com/).
* [Developing jQuery Mobile](http://forum.jquery.com/developing-jquery-mobile)
@@ -41,12 +41,12 @@ To ensure that you'll get a useful answer in no time, please consider the follow
* Ensure your markup is valid.
* Use Firebug/Developer Tools to see if you have an exception.
-* Use Firebug/Developer Tools to inspect the html classes, css. etc.
-* Try expected resulting html and css without javascript/jQuery and see if the problem could be isolated to those two.
+* Use Firebug/Developer Tools to inspect the HTML classes, CSS, etc.
+* Try expected resulting HTML and CSS without JavaScript/jQuery and see if the problem could be isolated to those two.
* Reduce to a minimal test case (keep removing things until the problem goes away, etc.)
-* Provide that test case as part of your mail. Either upload it somewhere or post it on jsbin.com.
+* Provide that test case as part of your mail. Either upload it somewhere or post it on [jsbin.com](http://jsbin.com/).
-In general, keep your question short and focused and provide only essential details - others can be added when required.
+In general, keep your question short and focused and provide only essential details others can be added when required.
### Mailing List Archives
@@ -71,8 +71,8 @@ The IRC Channel is best if you need quick help with any of the following:
* JavaScript
* jQuery syntax
-* problem solving
-* strange bugs.
+* Problem solving
+* Strange bugs
If your problem is more in-depth, we may ask you to post to the mailing list, or the bug tracker, so that we can help you in a more-suitable environment.
View
128 page/about-jquery/how-jquery-works.md
@@ -5,22 +5,22 @@ level: beginner
### jQuery: The Basics
This is a basic tutorial, designed to help you get started using jQuery. If you
-don't have a test page setup yet, start by creating the following HTML page:
+don't have a test page setup yet, start by creating the following HTML page:
```
<!doctype html>
<html>
- <head>
- <meta charset="utf-8">
- <title>Demo</title>
- </head>
- <body>
- <a href="http://jquery.com/">jQuery</a>
- <script src="jquery.js"></script>
- <script>
- // Your code goes here
- </script>
- </body>
+<head>
+ <meta charset="utf-8">
+ <title>Demo</title>
+</head>
+<body>
+ <a href="http://jquery.com/">jQuery</a>
+ <script src="jquery.js"></script>
+ <script>
+ // Your code goes here
+ </script>
+</body>
</html>
```
@@ -30,77 +30,77 @@ and store the `jquery.js` file in the same directory as your HTML file.
### Launching Code on Document Ready
-To ensure that their code runs after the browser finishes loading the document,
+To ensure that their code runs after the browser finishes loading the document,
many JavaScript programmers wrap their code in an `onload` function:
```
window.onload = function() {
- alert("welcome");
+ alert( "welcome" );
}
```
Unfortunately, the code doesn't run until all images are finished downloading, including banner ads.
-To run code as soon as the `document` is ready to be manipulated, jQuery has a statement
-known as the [ ready event ](http://api.jquery.com/ready):
+To run code as soon as the `document` is ready to be manipulated, jQuery has a statement
+known as the [ready event](http://api.jquery.com/ready):
```
-$( document ).ready( function() {
- // Your code here
+$( document ).ready(function() {
+ // Your code here
});
```
For example, inside the `ready` event, you can add a click handler to the link:
```
$( document ).ready(function() {
- $("a").click(function( event ) {
- alert("Thanks for visiting!");
- });
+ $( "a" ).click(function( event ) {
+ alert( "Thanks for visiting!" );
+ });
});
```
-Save your HTML file and reload the test page in your browser.
-Clicking the link should now first display an alert pop-up,
+Save your HTML file and reload the test page in your browser.
+Clicking the link should now first display an alert pop-up,
then continue with the default behavior of navigating to http://jquery.com.
-For `click` and most other [events](http://api.jquery.com/category/events/),
+For `click` and most other [events](http://api.jquery.com/category/events/),
you can prevent the default behavior by calling `event.preventDefault()` in the event handler:
```
$( document ).ready(function() {
- $("a").click(function( event ) {
- alert("As you can see, the link no longer took you to jquery.com");
- event.preventDefault();
- });
+ $( "a" ).click(function( event ) {
+ alert( "As you can see, the link no longer took you to jquery.com" );
+ event.preventDefault();
+ });
});
```
### Complete Example
The following example illustrates the click handling code discussed above,
embedded directly in the HTML `<body>`. Note that in practice,
-it is usually better to place your code in a separate JS file
+it is usually better to place your code in a separate JS file
and load it on the page with a `<script>` element's `src` attribute.
```
<!doctype html>
<html>
- <head>
- <meta charset="utf-8">
- <title>Demo</title>
- </head>
- <body>
- <a href="http://jquery.com/">jQuery</a>
- <script src="jquery.js"></script>
- <script>
- $( document ).ready(function() {
- $("a").click(function( event ) {
- alert("The link will no longer take you to jquery.com");
- event.preventDefault();
- });
- });
- </script>
- </body>
+<head>
+ <meta charset="utf-8">
+ <title>Demo</title>
+</head>
+<body>
+ <a href="http://jquery.com/">jQuery</a>
+ <script src="jquery.js"></script>
+ <script>
+ $( document ).ready(function() {
+ $( "a" ).click(function( event ) {
+ alert( "The link will no longer take you to jquery.com" );
+ event.preventDefault();
+ });
+ });
+ </script>
+</body>
</html>
```
@@ -114,24 +114,24 @@ First, add some style information into the `<head>` of the document, like this:
```
<style>
- a.test {
- font-weight: bold;
- }
+a.test {
+ font-weight: bold;
+}
</style>
```
Next, add the [addClass()](http://api.jquery.com/addClass) call to the script:
```
-$("a").addClass("test");
+$( "a" ).addClass( "test" );
```
All `a` elements are now bold.
To remove an existing `class`, use [removeClass()](http://api.jquery.com/removeClass):
```
-$("a").removeClass("test");
+$( "a" ).removeClass( "test" );
```
### Special Effects
@@ -141,9 +141,9 @@ to help you make your web sites stand out.
For example, if you create a click handler of:
```
-$("a").click(function( event ){
- event.preventDefault();
- $( this ).hide("slow");
+$( "a" ).click(function( event ){
+ event.preventDefault();
+ $( this ).hide( "slow" );
});
```
@@ -155,7 +155,7 @@ Unlike many other programming languages, JavaScript enables you to freely pass f
A *callback* is a function that is passed as an argument to another function and
is executed after its parent function has completed. Callbacks are special because
they patiently wait to execute until their parent finishes.
-Meanwhile, the browser can be executing other functions or doing all sorts of other work.
+Meanwhile, the browser can be executing other functions or doing all sorts of other work.
To use callbacks, it is important to know how to pass them into their parent function.
@@ -172,31 +172,31 @@ When [$.get](http://api.jquery.com/jQuery.get/) finishes getting the page `myhtm
### Callback *with* Arguments
-Executing callbacks with arguments can be tricky.
+Executing callbacks with arguments can be tricky.
#### Wrong
This code example will ***not*** work:
```
-$.get( "myhtmlpage.html", myCallBack(param1, param2) );
+$.get( "myhtmlpage.html", myCallBack( param1, param2 ) );
```
-The reason this fails is that the code executes `myCallBack( param1, param2 )` immediately
-and then passes the myCallBack's *return value* as the second parameter to `$.get`.
-We actually want to pass the function `myCallBack`, not `myCallBack( param1, param2)`'s return value
+The reason this fails is that the code executes `myCallBack( param1, param2 )` immediately
+and then passes myCallBack's *return value* as the second parameter to `$.get`.
+We actually want to pass the function `myCallBack`, not `myCallBack( param1, param2 )`'s return value
(which might or might not be a function). So, how to pass in `myCallBack` *and* include its arguments?
#### Right
To defer executing `myCallBack` with its parameters, you can use an anonymous function as a wrapper.
Note the use of `function() {`. The anonymous function does exactly one thing: calls
-`myCallBack`, with the values of `param1` and `param2`.
+`myCallBack`, with the values of `param1` and `param2`.
```
- $.get( "myhtmlpage.html", function() {
- myCallBack( param1, param2 );
- });
+$.get( "myhtmlpage.html", function() {
+ myCallBack( param1, param2 );
+});
```
When `$.get` finishes getting the page `myhtmlpage.html`, it executes the anonymous function,
-which executes `myCallBack( param1, param2 )`.
+which executes `myCallBack( param1, param2 )`.
View
16 page/about.md
@@ -1,6 +1,6 @@
---
title: About This Site
-customFields:
+customFields:
-
key: "is_chapter"
value: 0
@@ -15,7 +15,7 @@ how to do exactly what they need to do.
However, API documentation alone cannot serve as a guide to solving problems
and fostering a true understanding of web development. Over the years, an
-ecosystem of blog posts, books, support forums and channels has grown to help
+ecosystem of blog posts, books, support forums, and channels has grown to help
cover the **hows** and **whys** of developing with jQuery, as well as explaining
best practices, techniques, and workarounds for common problems. This type of
documentation has been invaluable resource for millions of people, but the
@@ -29,8 +29,8 @@ curate this information in order to provide this crucial "narrative
documentation" to our community and serve the following goals:
1. Provide our **users** with a digestible reference on all aspects of using jQuery, from the basics of getting started and performing common tasks to more advanced topics like approaches to structuring code and where jQuery fits into modern web application development.
-2. Provide our **contributors** a central, open place to collaborate and provide a dependable, highly sharable resource that will improve our users' support experiences
-3. Foster an environment by which users are encouraged to become contributors and build the skills to help them work on jQuery -- or any other open source project!
+2. Provide our **contributors** a central, open place to collaborate and provide a dependable, highly sharable resource that will improve our users' support experiences.
+3. Foster an environment by which users are encouraged to become contributors and build the skills to help them work on jQuery or any other open source project!
In order to achieve these goals, all of [this site's content is maintained
publicly on GitHub](http://github.com/jquery/learn.jquery.com) and is licensed
@@ -53,18 +53,18 @@ for some sort of "learning center."
The second is [docs.jquery.com](http://docs.jquery.com), that erstwhile
chestnut still living out its final days before it will be shut down in early
2013. Since we've moved the API documentation for jQuery Core off that domain,
-we needed a place that could serve a similar need -- documentation (that anyone
-can contribute to) that gets into the "how-to" and FAQs -- without clumsy
+we needed a place that could serve a similar need documentation (that anyone
+can contribute to) that gets into the "how-to" and FAQs without clumsy
barriers to entry like finding the right person to set you up with a special
wiki account and forcing all authoring into a `textarea`.
-<h2><a name="beta">About the Beta</a></h2>
+<h2><a name="beta">About the Beta</a></h2>
Though this resource will never truly be "done," the current version of this
site should still be considered something of a preview. We still have a number
of improvements we want to make to the content, user experience, and site build
before we're ready to call it a "final release." At the same time, however,
it's important for us to open the doors now so we can begin providing better
-docs to people who need the right away and spread the word about this effort.
+docs to people who need them right away and spread the word about this effort.
If you're interested in helping us reach the finish line, we invite you to
please read more about how [you can get involved with contributing](/contributing)!
View
10 page/ajax.md
@@ -7,14 +7,14 @@ customFields:
value: "refresh"
---
-Traditionally webpages required reloading to update their content. For web-based email this meant that users had to manually reload their inbox to check and see if they had new mail. This had huge drawbacks: it was slow and it required user input. When the user reloaded their inbox, the server had to reconstruct the entire web page and resend all of the HTML, CSS, JavaScript, as well as the user's email. This was hugely inefficient. Ideally, the server should only have to send the user's new messages, not the entire page. By 2003 all the major browsers, solved this issue by adopting the XMLHttpRequest (XHR) object, allowing browsers to communicate with the server without requiring a page reload.
+Traditionally webpages required reloading to update their content. For web-based email this meant that users had to manually reload their inbox to check and see if they had new mail. This had huge drawbacks: it was slow and it required user input. When the user reloaded their inbox, the server had to reconstruct the entire web page and resend all of the HTML, CSS, JavaScript, as well as the user's email. This was hugely inefficient. Ideally, the server should only have to send the user's new messages, not the entire page. By 2003, all the major browsers solved this issue by adopting the XMLHttpRequest (XHR) object, allowing browsers to communicate with the server without requiring a page reload.
-The XMLHttpRequest object is part of a technology called Ajax (Asynchronous JavaScript and XML). Using Ajax, data could then be passed between the browser and the server, using the XMLHttpRequest API, without having to reload the web page. With the widespread adoption of the XMLHttpRequest object it quickly became possible to build web applications like Google Maps, and GMail that used XMLHttpRequest to get new map tiles, or new email without having to reload the entire page.
+The XMLHttpRequest object is part of a technology called Ajax (Asynchronous JavaScript and XML). Using Ajax, data could then be passed between the browser and the server, using the XMLHttpRequest API, without having to reload the web page. With the widespread adoption of the XMLHttpRequest object it quickly became possible to build web applications like Google Maps, and Gmail that used XMLHttpRequest to get new map tiles, or new email without having to reload the entire page.
-Ajax requests are triggered by JavaScript code; your code sends a request to a URL, and when it receives a response, a callback function can be triggered to handle the response. Because the request is asynchronous, the rest of your code continues to execute while the request is being processed, so its imperative that a callback be used to handle the response.
+Ajax requests are triggered by JavaScript code; your code sends a request to a URL, and when it receives a response, a callback function can be triggered to handle the response. Because the request is asynchronous, the rest of your code continues to execute while the request is being processed, so it's imperative that a callback be used to handle the response.
Unfortunately, different browsers implement the Ajax API differently. Typically this meant that developers would have to account for all the different browsers to ensure that Ajax would work universally. Fortunately, jQuery provides Ajax support that abstracts away painful browser differences. It offers both a full-featured `$.ajax()` method, and simple convenience methods such as `$.get()`, `$.getScript()`, `$.getJSON()`, `$.post()`, and `$().load()`.
-Most jQuery applications dont in fact use XML, despite the name Ajax; instead, they transport data as plain HTML or JSON (JavaScript Object Notation).
+Most jQuery applications don't in fact use XML, despite the name "Ajax"; instead, they transport data as plain HTML or JSON (JavaScript Object Notation).
-In general, Ajax does not work across domains. For instance, a webpage loaded from example1.com is unable to make an Ajax request to example2.com as it would violate the same origin policy. As a work around, JSONP (JSON with Padding) uses `<script>` tags to load files containing arbitrary JavaScript content and JSON, from another domain. More recently browsers have implemented a technology called Cross-origin resource sharing (CORS), that allows Ajax requests to different domains.
+In general, Ajax does not work across domains. For instance, a webpage loaded from example1.com is unable to make an Ajax request to example2.com as it would violate the same origin policy. As a work around, JSONP (JSON with Padding) uses `<script>` tags to load files containing arbitrary JavaScript content and JSON, from another domain. More recently browsers have implemented a technology called Cross-Origin Resource Sharing (CORS), that allows Ajax requests to different domains.
View
93 page/ajax/ajax-and-forms.md
@@ -6,16 +6,17 @@ attribution:
- jQuery Fundamentals
---
-jQuerys ajax capabilities can be especially useful when dealing with forms. There are several advantages, which can range from serialization, to simple client-side validation (e.g. "Sorry, that username is taken"), to [prefilters](http://api.jquery.com/extending-ajax/#Prefilters) (explained below), and even more!
+jQuery's ajax capabilities can be especially useful when dealing with forms. There are several advantages, which can range from serialization, to simple client-side validation (e.g. "Sorry, that username is taken"), to [prefilters](http://api.jquery.com/extending-ajax/#Prefilters) (explained below), and even more!
### Serialization
+
Serializing form inputs in jQuery is extremely easy. Two methods come supported natively: `.serialize()` and `.serializeArray()`. While the names are fairly self-explanatory, there are many advantages to using them.
The `.serialize()` method serializes a form's data into a query string. For the element's value to be serialized, it **must** have a `name` attribute. Please note that values from inputs with a type of `checkbox` or `radio` are included only if they are checked.
```
// Turning form data into a query string
-$("#myForm").serialize();
+$( "#myForm" ).serialize();
// creates a query string like this:
// field_1=something&field2=somethingElse
@@ -25,108 +26,86 @@ While plain old serialization is great, sometimes your application would work be
```
// Creating an array of objects containing form data
-$("#myForm").serializeArray();
+$( "#myForm" ).serializeArray();
// creates a structure like this:
// [
// {
-//
// name : "field_1",
// value : "something"
-//
// },
// {
-//
// name : "field_2",
// value : "somethingElse"
-//
// }
// ]
```
### Client-side validation
-Client-side validation is, much like many other things, extremely easy using jQuery. While there are several cases developers can test for, some of the most common ones are: presence of a required input, valid usernames/emails/phone numbers/etc..., or checking an "I agree..." box.
+Client-side validation is, much like many other things, extremely easy using jQuery. While there are several cases developers can test for, some of the most common ones are: presence of a required input, valid usernames/emails/phone numbers/etc&hellip;, or checking an "I agree&hellip;" box.
Please note that it is advisable that you also perform server-side validation for your inputs. However, it typically makes for a better user experience to be able to validate some things without submitting the form.
With that being said, let's jump on in to some examples! First, we'll see how easy it is to check if a required field doesn't have anything in it. If it doesn't, then we'll `return false`, and prevent the form from processing.
```
// Using validation to check for the presence of an input
-$("#form").submit(function( event ) {
-
- // if .required's value's length is zero
- if ( $(".required").val().length === 0 ) {
-
- // usually show some kind of error message here
-
- // this prevents the form from submitting
- return false;
-
- } else {
-
- // run $.ajax here
-
- }
-
+$( "#form" ).submit(function( event ) {
+ // if .required's value's length is zero
+ if ( $( ".required" ).val().length === 0 ) {
+ // usually show some kind of error message here
+
+ // this prevents the form from submitting
+ return false;
+ } else {
+ // run $.ajax here
+ }
});
```
-Let's see how easy it is to check for invalid characters in a username:
+Let's see how easy it is to check for invalid characters in a phone number:
```
// Validate a phone number field
-$("#form").submit(function( event ) {
-
- var inputtedPhoneNumber = $("#phone").val();
- // match only numbers
- var phoneNumberRegex = ^\d*$/;
-
- // if the phone number doesn't match the regex
- if ( !phoneNumberRegex.test( inputtedPhoneNumber ) ) {
+$( "#form" ).submit(function( event ) {
+ var inputtedPhoneNumber = $( "#phone" ).val();
- // usually show some kind of error message here
+ // match only numbers
+ var phoneNumberRegex = /^\d*$/;
- // prevent the form from submitting
- return false;
-
- } else {
-
- // run $.ajax here
-
- }
+ // if the phone number doesn't match the regex
+ if ( !phoneNumberRegex.test( inputtedPhoneNumber ) ) {
+ // usually show some kind of error message here
+ // prevent the form from submitting
+ return false;
+ } else {
+ // run $.ajax here
+ }
});
```
### Prefiltering
A prefilter is a way to modify the ajax options before each request is sent (hence, the name `prefilter`).
-For example, say we would like to modify all crossDomain requests through a proxy. To do so with a prefilter is quite simple:
+For example, say we would like to modify all cross-domain requests through a proxy. To do so with a prefilter is quite simple:
```
// Using a proxy with a prefilter
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
-
- if ( options.crossDomain ) {
-
- options.url = "http://mydomain.net/proxy/" + encodeURIComponent( options.url );
-
- options.crossDomain = false;
-
- }
-
+ if ( options.crossDomain ) {
+ options.url = "http://mydomain.net/proxy/" + encodeURIComponent( options.url );
+ options.crossDomain = false;
+ }
});
```
You can pass in an optional argument before the callback function that specifies which `dataTypes` you'd like the prefilter to be applied to. For example, if we want our prefilter to only apply to `JSON` and `script` requests, we'd do:
```
-// Using the optional dataTypes argument">
+// Using the optional dataTypes argument
$.ajaxPrefilter( "json script", function( options, originalOptions, jqXHR ) {
-
- // do all of the prefiltering here, but only for
- // requests that indicate a dataType of "JSON" or "script"
-
+ // do all of the prefiltering here, but only for
+ // requests that indicate a dataType of "JSON" or "script"
});
```
View
23 page/ajax/ajax-events.md
@@ -2,25 +2,20 @@
title : Ajax Events
level: beginner
source: http://jqfundamentals.com/legacy
-attribution:
+attribution:
- jQuery Fundamentals
---
-Often, youll want to perform an operation whenever an Ajax requests starts or
-stops, such as showing or hiding a loading indicator. Rather than defining
+Often, you'll want to perform an operation whenever an Ajax requests starts or
+stops, such as showing or hiding a loading indicator. Rather than defining
this behavior inside every Ajax request, you can bind Ajax events to elements
-just like you'd bind other events. For a complete list of Ajax events, visit
-[ Ajax Events documentation on docs.jquery.com ]( http://docs.jquery.com/Ajax_Events ).
+just like you'd bind other events. For a complete list of Ajax events, visit
+[Ajax Events documentation on docs.jquery.com](http://docs.jquery.com/Ajax_Events).
```
// Setting up a loading indicator using Ajax Events
-$("#loading_indicator").ajaxStart(function() {
-
- $( this ).show();
-
- }).ajaxStop(function() {
-
- $( this ).hide();
-
+$( "#loading_indicator" ).ajaxStart(function() {
+ $( this ).show();
+}).ajaxStop(function() {
+ $( this ).hide();
});
-
```
View
135 page/ajax/jquery-ajax-methods.md
@@ -18,65 +18,58 @@ syntax is more easily understandable, in my opinion.
jQuery’s core `$.ajax()` method is a powerful and straightforward way of creating
Ajax requests. It takes a configuration object that contains all the
-instructions jQuery requires to complete the request. The `$.ajax` method is
+instructions jQuery requires to complete the request. The `$.ajax()` method is
particularly valuable because it offers the ability to specify both success and
-failure callbacks. Also, its ability to take a configuration object that can
-be defined separately makes it easier to write reusable code. For complete
+failure callbacks. Also, its ability to take a configuration object that can
+be defined separately makes it easier to write reusable code. For complete
documentation of the configuration options, visit
[http://api.jquery.com/jQuery.ajax/](http://api.jquery.com/jQuery.ajax/ "$.ajax
documentation on api.jquery.com").
```
// Using the core $.ajax() method
$.ajax({
-
- // the URL for the request
- url : "post.php",
-
- // the data to send
- // (will be converted to a query string)
- data : {
- id : 123
- },
-
- // whether this is a POST or GET request
- type : "GET",
-
- // the type of data we expect back
- dataType : "json",
-
- // code to run if the request succeeds;
- // the response is passed to the function
- success : function( json ) {
- $("<h1/>").text( json.title ).appendTo("body");
- $("<div class=\"content\"/>").html( json.html ).appendTo("body");
- },
-
- // code to run if the request fails;
- // the raw request and status codes are
- // passed to the function
- error : function( xhr, status ) {
- alert("Sorry, there was a problem!");
- },
-
- // code to run regardless of success or failure
- complete : function( xhr, status ) {
- alert("The request is complete!");
- }
-
+ // the URL for the request
+ url: "post.php",
+
+ // the data to send (will be converted to a query string)
+ data: {
+ id: 123
+ },
+
+ // whether this is a POST or GET request
+ type: "GET",
+
+ // the type of data we expect back
+ dataType : "json",
+
+ // code to run if the request succeeds;
+ // the response is passed to the function
+ success: function( json ) {
+ $( "<h1/>" ).text( json.title ).appendTo( "body" );
+ $( "<div class=\"content\"/>").html( json.html ).appendTo( "body" );
+ },
+
+ // code to run if the request fails; the raw request and
+ // status codes are passed to the function
+ error: function( xhr, status ) {
+ alert( "Sorry, there was a problem!" );
+ },
+
+ // code to run regardless of success or failure
+ complete: function( xhr, status ) {
+ alert( "The request is complete!" );
+ }
});
```
-<div class="note" >
-### Note
-
-A note about the dataType setting: if the server sends back data that is in a
+**Note:** A note about the `dataType` setting: if the server sends back data that is in a
different format than you specify, your code may fail, and the reason will not
-always be clear, because the HTTP response code will not show an error. When
+always be clear, because the HTTP response code will not show an error. When
working with Ajax requests, make sure your server is sending back the data type
-you're asking for, and verify that the Content-type header is accurate for the
-data type. For example, for JSON data, the Content-type header should be
-`application/json`. </div>
+you're asking for, and verify that the `Content-type` header is accurate for the
+data type. For example, for JSON data, the `Content-type` header should be
+`application/json`.
### `$.ajax()` Options
@@ -94,8 +87,8 @@ of other code until the response is received.
#### cache
-Whether to use a cached response if available. Defaults to true for all
-dataTypes except "script" and "jsonp". When set to false, the URL will simply
+Whether to use a cached response if available. Defaults to `true` for all
+`dataType`s except "script" and "jsonp". When set to `false`, the URL will simply
have a cachebusting parameter appended to it.
#### complete
@@ -118,7 +111,7 @@ string, such as `foo=bar&amp;baz=bim`.
#### dataType
The type of data you expect back from the server. By default, jQuery will look
-at the MIME type of the response if no dataType is specified.
+at the MIME type of the response if no `dataType` is specified.
#### error
@@ -133,7 +126,7 @@ Defaults to "callback".
#### success
A callback function to run if the request succeeds. The function receives the
-response data (converted to a JavaScript object if the dataType was JSON), as
+response data (converted to a JavaScript object if the `dataType` was JSON), as
well as the text status of the request and the raw request object.
#### timeout
@@ -142,7 +135,7 @@ The time in milliseconds to wait before considering the request a failure.
#### traditional
-Set to true to use the param serialization style in use prior to jQuery 1.4.
+Set to `true` to use the param serialization style in use prior to jQuery 1.4.
For details, see
[http://api.jquery.com/jQuery.param/](http://api.jquery.com/jQuery.param/
"$.param documentation on api.jquery.com").
@@ -198,11 +191,7 @@ The URL for the request. Required.
The data to be sent to the server. Optional. This can either be an object or a
query string, such as `foo=bar&amp;baz=bim`.
-<div class="note">
-### Note
-
-This option is not valid for `$.getScript`.
-</div>
+**Note:** This option is not valid for `$.getScript`.
#### success callback
@@ -215,36 +204,30 @@ object.
The type of data you expect back from the server. Optional.
-<div class="note">
-### Note
-
-This option is only applicable for methods that don't already specify the data
-type in their name. </div>
+**Note:** This option is only applicable for methods that don't already specify the data
+type in their name.
```
// Using jQuery's Ajax convenience methods
-// get plain text or html
+
+// get plain text or HTML
$.get( "/users.php", {
- userId : 1234
+ userId: 1234
}, function( resp ) {
- console.log( resp ); // server response
+ console.log( resp ); // server response
});
// add a script to the page, then run a function defined in it
$.getScript( "/static/js/myScript.js", function() {
-
- functionFromMyScript();
-
+ functionFromMyScript();
});
// get JSON-formatted data from the server
$.getJSON( "/details.php", function( resp ) {
-
- // log each key in the response data
- $.each( resp, function( key, value ) {
- console.log( key + " : " + value );
- });
-
+ // log each key in the response data
+ $.each( resp, function( key, value ) {
+ console.log( key + " : " + value );
+ });
});
```
@@ -258,12 +241,12 @@ will fetch only the matching content from the returned HTML.
```
// Using $.fn.load to populate an element
-$("#newContent").load("/foo.html");
+$( "#newContent" ).load( "/foo.html" );
```
```
// Using $.fn.load to populate an element based on a selector
-$("#newContent").load( "/foo.html #myDiv h1:first:", function( html ) {
- alert("Content updated!"");
+$( "#newContent" ).load( "/foo.html #myDiv h1:first:", function( html ) {
+ alert( "Content updated!" );
});
```
View
55 page/ajax/key-concepts.md
@@ -2,27 +2,27 @@
title : Key Concepts
level: beginner
source: http://jqfundamentals.com/legacy
-attribution:
+attribution:
- jQuery Fundamentals
---
Proper use of Ajax-related jQuery methods requires understanding some key
concepts first.
-### GET vs. Post
+### GET vs. POST
-The two most common methods for sending a request to a server are GET and
-POST. It’s important to understand the proper application of each.
+The two most common "methods" for sending a request to a server are GET and
+POST. It's important to understand the proper application of each.
The GET method should be used for non-destructive operations — that is,
-operations where you are only getting data from the server, not changing data
-on the server. For example, a query to a search service might be a GET
-request. GET requests may be cached by the browser, which can lead to
-unpredictable behavior if you are not expecting it. GET requests generally
+operations where you are only "getting" data from the server, not changing data
+on the server. For example, a query to a search service might be a GET
+request. GET requests may be cached by the browser, which can lead to
+unpredictable behavior if you are not expecting it. GET requests generally
send all of their data in a query string.
The POST method should be used for destructive operations — that is, operations
-where you are changing data on the server. For example, a user saving a blog
-post should be a POST request. POST requests are generally not cached by the
+where you are changing data on the server. For example, a user saving a blog
+post should be a POST request. POST requests are generally not cached by the
browser; a query string can be part of the URL, but the data tends to be sent
separately as post data.
@@ -35,55 +35,50 @@ object. There are several options:
#### text
-For transporting simple strings
+For transporting simple strings.
#### html
-For transporting blocks of HTML to be placed on the page
+For transporting blocks of HTML to be placed on the page.
#### script
-For adding a new script to the page
+For adding a new script to the page.
#### json
-For transporting JSON-formatted data, which can include strings, arrays, and objects
+For transporting JSON-formatted data, which can include strings, arrays, and objects.
-<div class="note">
-### Note
-
-As of jQuery 1.4, if the JSON data sent by your server isn't properly
-formatted, the request may fail silently. See
+**Note:** As of jQuery 1.4, if the JSON data sent by your server isn't properly
+formatted, the request may fail silently. See
[http://json.org](http://json.org) for details on properly formatting JSON, but
as a general rule, use built-in language methods for generating JSON on the
server to avoid syntax issues.
#### jsonp
-For transporting JSON data from another domain
+For transporting JSON data from another domain.
#### xml
-For transporting data in a custom XML schema
+For transporting data in a custom XML schema.
I am a strong proponent of using the JSON format in most cases, as it provides
the most flexibility. It is especially useful for sending both HTML and data at
the same time.
### A is for Asynchronous
-The asynchronicity of Ajax catches many new jQuery users off guard. Because
+The asynchronicity of Ajax catches many new jQuery users off guard. Because
Ajax calls are asynchronous by default, the response is not immediately
-available. Responses can only be handled using a callback. So, for example,
+available. Responses can only be handled using a callback. So, for example,
the following code will not work:
```
var response;
$.get( "foo.php", function( r ) {
-
- response = r;
-
+ response = r;
});
console.log( response ); // undefined
@@ -95,14 +90,14 @@ returned, if any.
```
$.get( "foo.php", function( response ) {
- console.log( response ); // server response
+ console.log( response ); // server response
});
```
### Same-Origin Policy and JSONP
In general, Ajax requests are limited to the same protocol (http or https), the
-same port, and the same domain as the page making the request. This limitation
+same port, and the same domain as the page making the request. This limitation
does not apply to scripts that are loaded via jQuery's Ajax methods.
The other exception is requests targeted at a JSONP service on another domain.
@@ -114,9 +109,9 @@ data you requested, wrapped in a callback function you provide.
### Ajax and Firebug
Firebug (or the Webkit Inspector in Chrome or Safari) is an invaluable tool for
-working with Ajax requests. You can see Ajax requests as they happen in the
+working with Ajax requests. You can see Ajax requests as they happen in the
Console tab of Firebug (and in the Resources > XHR panel of Webkit Inspector),
and you can click on a request to expand it and see details such as the request
-headers, response headers, response content, and more. If something isn't
+headers, response headers, response content, and more. If something isn't
going as expected with an Ajax request, this is the first place to look to
track down what's wrong.
View
38 page/ajax/working-with-jsonp.md
@@ -2,45 +2,41 @@
title : Working with JSONP
level: beginner
source: http://jqfundamentals.com/legacy
-attribution:
+attribution:
- jQuery Fundamentals
---
The advent of JSONP — essentially a consensual cross-site scripting hack — has
-opened the door to powerful mashups of content. Many prominent sites provide
-JSONP services, allowing you access to their content via a predefined API. A
+opened the door to powerful mashups of content. Many prominent sites provide
+JSONP services, allowing you access to their content via a predefined API. A
particularly great source of JSONP-formatted data is the [Yahoo! Query
Language](http://developer.yahoo.com/yql/console/), which we'll use in the
following example to fetch news about cats.
```
// Using YQL and JSONP
$.ajax({
+ url: "http://query.yahooapis.com/v1/public/yql",
- url : "http://query.yahooapis.com/v1/public/yql",
+ // the name of the callback parameter, as specified by the YQL service
+ jsonp: "callback",
- // the name of the callback parameter,
- // as specified by the YQL service
- jsonp : "callback",
+ // tell jQuery we're expecting JSONP
+ dataType: "jsonp",
- // tell jQuery we're expecting JSONP
- dataType : "jsonp",
-
- // tell YQL what we want and that we want JSON
- data : {
- q : "select title,abstract,url from search.news where query=\"cat\"",
- format : "json"
- },
-
- // work with the response
- success : function( response ) {
- console.log( response ); // server response
- }
+ // tell YQL what we want and that we want JSON
+ data: {
+ q: "select title,abstract,url from search.news where query=\"cat\"",
+ format: "json"
+ },
+ // work with the response
+ success: function( response ) {
+ console.log( response ); // server response
+ }
});
```
jQuery handles all the complex aspects of JSONP behind-the-scenes — all we have
to do is tell jQuery the name of the JSONP callback parameter specified by YQL
("callback" in this case), and otherwise the whole process looks and feels like
a normal Ajax request.
-
View
47 page/code-organization/beware-anonymous-functions.md
@@ -2,7 +2,7 @@
title: Beware Anonymous Functions
level: beginner
source: http://jqfundamentals.com/legacy
-attribution:
+attribution:
- jQuery Fundamentals
---
@@ -13,44 +13,33 @@ your handlers and callbacks.
// BAD
$( document ).ready(function() {
- $("#magic").click(function( event ) {
+ $( "#magic" ).click(function( event ) {
+ $( "#yayeffects" ).slideUp(function() {
+ // ...
+ });
+ });
- $("#yayeffects").slideUp(function() {
-
- // ...
-
- });
-
- });
-
- $("#happiness").load( url + " #unicorns", function() {
-
- // ...
-
- });
+ $( "#happiness" ).load( url + " #unicorns", function() {
+ // ...
+ });
});
// BETTER
var PI = {
- onReady : function() {
-
- $("#magic").click( PI.candyMtn );
-
- $("#happiness").load( PI.url + " #unicorns", PI.unicornCb );
-
- },
-
- candyMtn : function( event ) {
-
- $("#yayeffects").slideUp( PI.slideCb );
+ onReady: function() {
+ $( "#magic" ).click( PI.candyMtn );
+ $( "#happiness" ).load( PI.url + " #unicorns", PI.unicornCb );
+ },
- },
+ candyMtn: function( event ) {
+ $( "#yayeffects" ).slideUp( PI.slideCb );
+ },
- slideCb : function() { ... },
+ slideCb: function() { ... },
- unicornCb : function() { ... }
+ unicornCb: function() { ... }
};
View
306 page/code-organization/concepts.md
@@ -2,7 +2,7 @@
title: Code Organization Concepts
level: beginner
source: http://jqfundamentals.com/legacy
-attribution:
+attribution:
- jQuery Fundamentals
---
@@ -51,24 +51,29 @@ options, and easing the path to reuse and refactoring.
```
// An object literal
var myFeature = {
- myProperty: "hello",
- myMethod: function() {
- console.log( myFeature.myProperty );
- },
- init: function( settings ) {
- myFeature.settings = settings;
- },
- readSettings : function() {
- console.log( myFeature.settings );
- }
+
+ myProperty: "hello",
+
+ myMethod: function() {
+ console.log( myFeature.myProperty );
+ },
+
+ init: function( settings ) {
+ myFeature.settings = settings;
+ },
+
+ readSettings: function() {
+ console.log( myFeature.settings );
+ }
+
};
myFeature.myProperty === "hello"; // true
myFeature.myMethod(); // "hello"
myFeature.init({
- foo: "bar"
+ foo: "bar"
});
myFeature.readSettings(); // { foo: "bar" }
@@ -84,28 +89,18 @@ How would we apply this pattern to jQuery code? Let's say that we had this code
written in the traditional jQuery style:
```
-// clicking on a list item loads some content
-// using the list item's ID and hides content
-// in sibling list items
+// clicking on a list item loads some content using the
+// list item's ID, and hides content in sibling list items
$( document ).ready(function() {
- $("#myFeature li").append("<div/>").click(function() {
-
- var $this = $( this );
-
- var $div = $this.find("div");
-
- $div.load( "foo.php?item=" + $this.attr("id"), function() {
-
- $div.show();
-
- $this.siblings().find("div").hide();
-
- }
-
- );
-
- });
+ $( "#myFeature li" ).append( "<div/>" ).click(function() {
+ var $this = $( this );
+ var $div = $this.find( "div" );
+ $div.load( "foo.php?item=" + $this.attr( "id" ), function() {
+ $div.show();
+ $this.siblings().find( "div" ).hide();
+ });
+ });
});
```
@@ -121,84 +116,61 @@ functionality later.
// Using an object literal for a jQuery feature
var myFeature = {
- init : function( settings ) {
-
- myFeature.config = {
- $items : $("#myFeature li"),
- $container : $("<div class='container'></div>"),
- urlBase : "/foo.php?item="
- };
-
- // allow overriding the default config
- $.extend( myFeature.config, settings );
-
- myFeature.setup();
-
- },
-
- setup : function() {
-
- myFeature.config.$items.each( myFeature.createContainer ).click( myFeature.showItem );
-
- },
-
- createContainer : function() {
-
- var $i = $( this );
-
- var $c = myFeature.config.$container.clone().appendTo( $i );
-
- $i.data( "container", $c );
-
- },
-
- buildUrl : function() {
-
- return myFeature.config.urlBase + myFeature.$currentItem.attr("id");
-
- },
-
- showItem : function() {
-
- var myFeature.$currentItem = $( this );
-
- myFeature.getContent( myFeature.showContent );
-
- },
-
- getContent : function( callback ) {
-
- var url = myFeature.buildUrl();
-
- myFeature.$currentItem.data("container").load( url, callback );
-
- },
-
- showContent : function() {
-
- myFeature.$currentItem.data("container").show();
-
- myFeature.hideContent();
-
- },
-
- hideContent : function() {
-
- myFeature.$currentItem.siblings().each(function() {
-
- $( this ).data("container").hide();
-
- });
-
- }
+ init: function( settings ) {
+ myFeature.config = {
+ $items: $( "#myFeature li" ),
+ $container: $( "<div class='container'></div>" ),
+ urlBase: "/foo.php?item="
+ };
+
+ // allow overriding the default config
+ $.extend( myFeature.config, settings );
+
+ myFeature.setup();
+ },
+
+ setup: function() {
+ myFeature.config.$items.each( myFeature.createContainer ).click( myFeature.showItem );
+ },
+
+ createContainer: function() {
+ var $i = $( this );
+ var $c = myFeature.config.$container.clone().appendTo( $i );
+ $i.data( "container", $c );
+ },
+
+ buildUrl: function() {
+ return myFeature.config.urlBase + myFeature.$currentItem.attr( "id" );
+ },
+
+ showItem: function() {
+ var myFeature.$currentItem = $( this );
+ myFeature.getContent( myFeature.showContent );
+ },
+
+ getContent: function( callback ) {
+ var url = myFeature.buildUrl();
+ myFeature.$currentItem.data( "container" ).load( url, callback );
+ },
+
+ showContent: function() {
+ myFeature.$currentItem.data( "container" ).show();
+ myFeature.hideContent();
+ },
+
+ hideContent: function() {
+ myFeature.$currentItem.siblings().each(function() {
+ $( this ).data( "container" ).hide();
+ });
+ }
};
$( document ).ready( myFeature.init );
```
The first thing you'll notice is that this approach is obviously far longer
-than the original -- again, if this were the extent of our application, using an
+than the original again, if this were the extent of our application, using an
object literal would likely be overkill. Assuming it's not the extent of our
application, though, we've gained several things:
@@ -227,31 +199,30 @@ desired.
// The module pattern
var feature = (function() {
- // private variables and functions
- var privateThing = "secret";
- var publicThing = "not secret";
- var changePrivateThing = function() {
- privateThing = "super secret";
- };
+ // private variables and functions
+ var privateThing = "secret";
+ var publicThing = "not secret";
- var sayPrivateThing = function() {
- console.log( privateThing );
- changePrivateThing();
- };
+ var changePrivateThing = function() {
+ privateThing = "super secret";
+ };
- // public API
- return {
- publicThing: publicThing,
- sayPrivateThing: sayPrivateThing
- };
+ var sayPrivateThing = function() {
+ console.log( privateThing );
+ changePrivateThing();
+ };
+
+ // public API
+ return {
+ publicThing: publicThing,
+ sayPrivateThing: sayPrivateThing
+ };
})();
feature.publicThing; // "not secret"
-
-// logs "secret" and changes the value
-// of privateThing
+// logs "secret" and changes the value of privateThing
feature.sayPrivateThing();
```
@@ -276,47 +247,56 @@ of the module, `showItemByIndex()`.
// Using the module pattern for a jQuery feature
$( document ).ready(function() {
- var feature = (function() {
-
- var $items = $("#myFeature li");
- var $container = $("<div class='container'></div>");
- var $currentItem = null;
- var urlBase = "/foo.php?item=";
- var createContainer = function() {
- var $i = $( this );
- var $c = $container.clone().appendTo( $i );
- $i.data( "container", $c );
- },
- buildUrl = function() {
- return urlBase + $currentItem.attr("id");
- },
- showItem = function() {
- $currentItem = $( this );
- getContent( showContent );
- },
- showItemByIndex = function( idx ) {
- $.proxy( showItem, $items.get( idx ) );
- },
- getContent = function( callback ) {
- $currentItem.data("container").load( buildUrl(), callback );
- },
- showContent = function() {
- $currentItem.data("container").show();
- hideContent();
- },
- hideContent = function() {
- $currentItem.siblings().each(function() {
- $( this ).data("container").hide();
- });
- };
- $items.each( createContainer ).click( showItem );
-
- return {
- showItemByIndex: showItemByIndex
- };
-
- })();
-
- feature.showItemByIndex( 0 );
+ var feature = (function() {
+
+ var $items = $( "#myFeature li" );
+ var $container = $( "<div class='container'></div>" );
+ var $currentItem = null;
+ var urlBase = "/foo.php?item=";
+
+ var createContainer = function() {
+ var $i = $( this );
+ var $c = $container.clone().appendTo( $i );
+ $i.data( "container", $c );
+ },
+
+ buildUrl = function() {
+ return urlBase + $currentItem.attr( "id" );
+ },
+
+ showItem = function() {
+ $currentItem = $( this );
+ getContent( showContent );
+ },
+
+ showItemByIndex = function( idx ) {
+ $.proxy( showItem, $items.get( idx ) );
+ },
+
+ getContent = function( callback ) {
+ $currentItem.data( "container" ).load( buildUrl(), callback );
+ },
+
+ showContent = function() {
+ $currentItem.data( "container" ).show();
+ hideContent();
+ },
+
+ hideContent = function() {
+ $currentItem.siblings().each(function() {
+ $( this ).data( "container" ).hide();
+ });
+ };
+
+ $items.each( createContainer ).click( showItem );
+
+ return {
+ showItemByIndex: showItemByIndex
+ };
+
+ })();
+
+ feature.showItemByIndex( 0 );
+
});
```
View
58 page/code-organization/deferreds.md
@@ -2,7 +2,7 @@
title: Deferreds
level: advanced
source: http://msdn.microsoft.com/en-us/magazine/gg723713.aspx
-attribution:
+attribution:
- Julian Aubourg <j@ubourg.net>
- Addy Osmani <addyosmani@gmail.com>
- Andree Hansson <peolanha@gmail.com>
@@ -18,7 +18,7 @@ object: they will be called once the request has actually completed.
##Promises
-In its most basic form, a 'promise' is a model that provides a solution
+In its most basic form, a "promise" is a model that provides a solution
for the concept of deferred (or future) results in software engineering.
The main idea behind it is something we've already covered: rather than
executing a call which may result in blocking, we instead return a
@@ -30,10 +30,10 @@ common problem that's faced is having an unknown knowledge of the API
server's latency at a given time so it's possible that other parts of
your application may be blocked from running until a result from it is
returned. Deferreds provide a better solution to this problem, one which
-is void of 'blocking' effects and completely decoupled.
+is void of "blocking" effects and completely decoupled.
The [Promise/A](http://wiki.commonjs.org/wiki/Promises/A) proposal
-defines a method called 'then' that can be used to register callbacks to
+defines a method called "then" that can be used to register callbacks to
a promise and, thus, get the future result when it is available. The
pseudo-code for dealing with a third party API that returns a promise
may look like:
@@ -42,68 +42,68 @@ may look like:
promise = callToAPI( arg1, arg2, ...);
promise.then(function( futureValue ) {
- /* handle futureValue */
+ /* handle futureValue */
});
-
+
promise.then(function( futureValue ) {
- /* do something else */
+ /* do something else */
});
```
Furthermore, a promise can actually end up being in two different
states:
-- resolved: in which case data is available
-- rejected: in which case something went wrong and no value is
+- Resolved: in which case data is available
+- Rejected: in which case something went wrong and no value is
available
-Thankfully, the 'then' method accepts two parameters: one for when the
+Thankfully, the "then" method accepts two parameters: one for when the
promise was resolved, another for when the promise was rejected. If we
get back to pseudo-code, we may do things like:
```
-promise.then( function( futureValue ) {
- /* we got a value */
-} , function() {
- /* something went wrong */
-} );
+promise.then(function( futureValue ) {
+ /* we got a value */
+}, function() {
+ /* something went wrong */
+});
```
In the case of certain applications, it is necessary to have several
results returned before your application can continue at all (for
example, displaying a dynamic set of options on a screen before a user
is able to select the option that interests them). Where this is the
-case, a method called 'when' exists, which can be used to perform some
+case, a method called "when" exists, which can be used to perform some
action once all the promises have been fully fulfilled:
```
when(
- promise1,
- promise2,
- ...
+ promise1,
+ promise2,
+ ...
).then(function( futureValue1, futureValue2, ... ) {
- /* all promises have completed and are resolved */
+ /* all promises have completed and are resolved */
});
```
A good example is a scenario where you may have multiple concurrent
animations that are being run. Without keeping track of each callback
firing on completion, it can be difficult to truly establish once all
-your animations have finished running. Using promises and 'when' however
+your animations have finished running. Using promises and "when" however
this is very straightforward as each of your animations can effectively
-say 'we promise to let you know once we're done'. The compounded result
+say "we promise to let you know once we're done". The compounded result
of this means it's a trivial process to execute a single callback once
the animations are done. For example:
```
-var promise1 = $("#id1").animate().promise();
-var promise2 = $("#id2").animate().promise();
+var promise1 = $( "#id1" ).animate().promise();
+var promise2 = $( "#id2" ).animate().promise();
when(
- promise1,
- promise2
-).then(function(){
- /* once both animations have completed
- we can then run our additional logic */
+ promise1,
+ promise2
+).then(function() {
+ /* once both animations have completed
+ we can then run our additional logic */
});
```
View
320 page/code-organization/deferreds/examples.md
@@ -2,7 +2,7 @@
title: Deferred examples
level: advanced
source: http://msdn.microsoft.com/en-us/magazine/gg723713.aspx
-attribution:
+attribution:
- Julian Aubourg <j@ubourg.net>
- Addy Osmani <addyosmani@gmail.com>
- Andree Hansson <peolanha@gmail.com>
@@ -21,32 +21,32 @@ abstract away asynchronous behaviour and decouple our code.
When it comes to asynchronous tasks, caching can be a bit demanding
since you have to make sure a task is only performed once for a given
key. As a consequence, the code has to somehow keep track of inbound
-tasks.
+tasks.
```
$.cachedGetScript( url, callback1 );
$.cachedGetScript( url, callback2 );
```
-The caching mechanism has to make sure the url is only requested once
+The caching mechanism has to make sure the URL is only requested once
even if the script isn't in cache yet. This shows some logic
-to keep track of callbacks bound to a given url in order for the cache
+to keep track of callbacks bound to a given URL in order for the cache
system to properly handle both complete and inbound requests.
```
var cachedScriptPromises = {};
$.cachedGetScript = function( url, callback ) {
- if ( !cachedScriptPromises[ url ] ) {
- cachedScriptPromises[ url ] = $.Deferred(function( defer ) {
- $.getScript( url ).then( defer.resolve, defer.reject );
- }).promise();
- }
- return cachedScriptPromises[ url ].done( callback );
+ if ( !cachedScriptPromises[ url ] ) {
+ cachedScriptPromises[ url ] = $.Deferred(function( defer ) {
+ $.getScript( url ).then( defer.resolve, defer.reject );
+ }).promise();
+ }
+ return cachedScriptPromises[ url ].done( callback );
};
```
-One promise is cached per url. If there is no promise for the given url yet,
+One promise is cached per URL. If there is no promise for the given URL yet,
then a deferred is created and the request is issued. If it already exists, however,
the callback is attached to the existing deferred. The big advantage of this
solution is that it will handle both complete and inbound requests
@@ -66,28 +66,28 @@ when a key isn't in the cache yet:
```
$.createCache = function( requestFunction ) {
- var cache = {};
- return function( key, callback ) {
- if ( !cache[ key ] ) {
- cache[ key ] = $.Deferred(function( defer ) {
- requestFunction( defer, key );
- }).promise();
- }
- return cache[ key ].done( callback );
- };
+ var cache = {};
+ return function( key, callback ) {
+ if ( !cache[ key ] ) {
+ cache[ key ] = $.Deferred(function( defer ) {
+ requestFunction( defer, key );
+ }).promise();
+ }
+ return cache[ key ].done( callback );
+ };
}
```
-Now that the request logic is abstracted away, cachedGetScript can be rewritten
+Now that the request logic is abstracted away, `cachedGetScript` can be rewritten
as follows:
```
$.cachedGetScript = $.createCache(function( defer, url ) {
- $.getScript( url ).then( defer.resolve, defer.reject );
+ $.getScript( url ).then( defer.resolve, defer.reject );
});
```
-This will work because every call to createCache will create a new cache
+This will work because every call to `createCache` will create a new cache
repository and return a new cache-retrieval function.
#### Image loading
@@ -96,16 +96,16 @@ A cache can be used to ensure that the same image is not loaded multiple times.
```
$.loadImage = $.createCache(function( defer, url ) {
- var image = new Image();
- function cleanUp() {
- image.onload = image.onerror = null;
- }
- defer.then( cleanUp, cleanUp );
- image.onload = function() {
- defer.resolve( url );
- };
- image.onerror = defer.reject;
- image.src = url;
+ var image = new Image();
+ function cleanUp() {
+ image.onload = image.onerror = null;
+ }
+ defer.then( cleanUp, cleanUp );
+ image.onload = function() {
+ defer.resolve( url );
+ };
+ image.onerror = defer.reject;
+ image.src = url;
});
```
@@ -116,7 +116,7 @@ $.loadImage( "my-image.png" ).done( callback1 );
$.loadImage( "my-image.png" ).done( callback2 );
```
-will work regardless of whether my-image.png has already been loaded or
+will work regardless of whether `my-image.png` has already been loaded or
not, or if it is actually in the process of being loaded.
#### Caching Data API responses
@@ -126,15 +126,15 @@ page are also perfect candidates. For instance, the following:
```
$.searchTwitter = $.createCache(function( defer, query ) {
- $.ajax({
- url: "http://search.twitter.com/search.json",
- data: {
- q: query
- },
- dataType: "jsonp",
- success: defer.resolve,
- error: defer.reject
- });
+ $.ajax({
+ url: "http://search.twitter.com/search.json",
+ data: {
+ q: query
+ },
+ dataType: "jsonp",
+ success: defer.resolve,
+ error: defer.reject
+ });
});
```
@@ -154,32 +154,32 @@ also be used for timing purposes.
For instance, you may need to perform an action on the page after a
given amount of time so as to attract the user's attention to a specific
feature they may not be aware of or deal with a timeout (for a quiz
-question for instance). While setTimeout is good for most use-cases it
+question for instance). While `setTimeout` is good for most use-cases it
doesn't handle the situation when the timer is asked for later, even
after it has theoretically expired. We can handle that with the
following caching system:
```
var readyTime;
-
+
$(function() {
- readyTime = jQuery.now();
+ readyTime = jQuery.now();
});
-
+
$.afterDOMReady = $.createCache(function( defer, delay ) {
- delay = delay || 0;
- $(function() {
- var delta = $.now() - readyTime;
- if ( delta >= delay ) {
- defer.resolve();
- } else {
- setTimeout( defer.resolve, delay - delta );
- }
- });
+ delay = delay || 0;
+ $(function() {
+ var delta = $.now() - readyTime;
+ if ( delta >= delay ) {
+ defer.resolve();
+ } else {
+ setTimeout( defer.resolve, delay - delta );
+ }
+ });
});
```
-The new afterDOMReady helper method provides proper timing after the DOM
+The new `afterDOMReady` helper method provides proper timing after the DOM
is ready while ensuring the bare minimum of timers will be used. If the
delay is already expired, any callback will be called right away.
@@ -196,13 +196,13 @@ dealing with such a situation, one usually end up with code like this:
```
var buttonClicked = false;
-
+
$( "#myButton" ).click(function() {
- if ( !buttonClicked ) {
- buttonClicked = true;
- initializeData();
- showPanel();
- }
+ if ( !buttonClicked ) {
+ buttonClicked = true;
+ initializeData();
+ showPanel();
+ }
});
```
@@ -211,14 +211,14 @@ opened:
```
if ( buttonClicked ) {
- /* perform specific action */
+ /* perform specific action */
}
```
This is a very coupled solution. If you want to add some other action,
you have to edit the bind code or just duplicate it all. If you don't,
-your only option is to test for buttonClicked and you may lose that new
-action because the buttonClicked variable may be false and your new code
+your only option is to test for `buttonClicked` and you may lose that new
+action because the `buttonClicked` variable may be false and your new code
may never be executed.
We can do much better using deferreds (for simplification sake, the
@@ -228,24 +228,24 @@ multiple event types):
```
$.fn.bindOnce = function( event, callback ) {
- var element = $( this[ 0 ] ),
- defer = element.data( "bind_once_defer_" + event );
- if ( !defer ) {
- defer = $.Deferred();
- function deferCallback() {
- element.unbind( event, deferCallback );
- defer.resolveWith( this, arguments );
- }
- element.bind( event, deferCallback )
- element.data( "bind_once_defer_" + event , defer );
- }
- return defer.done( callback ).promise();
+ var element = $( this[ 0 ] ),
+ defer = element.data( "bind_once_defer_" + event );
+ if ( !defer ) {
+ defer = $.Deferred();
+ function deferCallback() {
+ element.unbind( event, deferCallback );
+ defer.resolveWith( this, arguments );
+ }
+ element.bind( event, deferCallback )
+ element.data( "bind_once_defer_" + event , defer );
+ }
+ return defer.done( callback ).promise();
};
```
The code works as follows:
-- check if the element already has a deferred attached for the given
+- Check if the element already has a deferred attached for the given
event
- if not, create it and make it so it is resolved when the event is
fired the first time around
@@ -258,15 +258,15 @@ But let's define a helper method first:
```
$.fn.firstClick = function( callback ) {
- return this.bindOnce( "click", callback );
+ return this.bindOnce( "click", callback );
};
```
Then the logic can be re-factored as follows:
```
var openPanel = $( "#myButton" ).firstClick();
-
+
openPanel.done( initializeData );
openPanel.done( showPanel );
```
@@ -275,7 +275,7 @@ If an action should be performed only when a panel is opened later on:
```
openPanel.done(function() {
- /* perform specific action */
+ /* perform specific action */
});
```
@@ -291,73 +291,72 @@ mix them together.
#### Requesting panel content on first click and opening said panel
Following is the code for a button that, when clicked, opens a panel.
-It requests its content over the wire and then fades the content in. Using
+It requests its content over the wire and then fades the content in. Using
the helpers defined earlier, it could be defined as:
```
$( "#myButton" ).firstClick(function() {
- var panel = $( "#myPanel" );
- $.when(
- $.get( "panel.html" ),
- panel.slideDownPromise()
- ).done(function( ajaxResponse ) {
- panel.html( ajaxResponse[ 0 ] ).fadeIn();
- });
+ var panel = $( "#myPanel" );
+ $.when(
+ $.get( "panel.html" ),
+ panel.slideDownPromise()
+ ).done(function( ajaxResponse ) {
+ panel.html( ajaxResponse[ 0 ] ).fadeIn();
+ });
});
```
#### Loading images in a panel on first click and opening said panel
-Another possible goal is to have the panel fade in, only after the button
+Another possible goal is to have the panel fade in, only after the button
has been clicked and after all of the images have been loaded.
-The html code for this would look something like:
+The HTML code for this would look something like:
```
<div id="myPanel">
- <img data-src="image1.png" />
- <img data-src="image2.png" />
- <img data-src="image3.png" />
- <img data-src="image4.png" />
+ <img data-src="image1.png" />
+ <img data-src="image2.png" />
+ <img data-src="image3.png" />
+ <img data-src="image4.png" />
</div>
```
-We use the data-src attribute to keep track of the real image location.
+We use the `data-src` attribute to keep track of the real image location.
The code to handle our use case using our promise helpers is as follows:
```
$( "#myButton" ).firstClick(function() {
-
- var panel = $( "#myPanel" ),
- promises = [];
-
- $( "img", panel ).each(function() {
- var image = $( this ),
- src = element.attr( "data-src" );
- if ( src ) {
- promises.push(
- $.loadImage( src ).then( function() {
- image.attr( "src", src );
- }, function() {
- image.attr( "src", "error.png" );
- } )
- );
- }
- });
-
- promises.push(
- panel.slideDownPromise()
- );
-
- $.when.apply( null, promises ).done(function() {
- panel.fadeIn();
- });
+ var panel = $( "#myPanel" ),
+ promises = [];
+
+