diff --git a/page/code-organization/beware-anonymous-functions.md b/page/code-organization/beware-anonymous-functions.md
index 8ce056b9..5890b408 100644
--- a/page/code-organization/beware-anonymous-functions.md
+++ b/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() { ... }
};
diff --git a/page/code-organization/concepts.md b/page/code-organization/concepts.md
index 612a479b..4de26973 100644
--- a/page/code-organization/concepts.md
+++ b/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,16 +51,21 @@ 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
@@ -68,7 +73,7 @@ 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("
").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( "" ).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,76 +116,53 @@ functionality later.
// Using an object literal for a jQuery feature
var myFeature = {
- init : function( settings ) {
-
- myFeature.config = {
- $items : $("#myFeature li"),
- $container : $(""),
- 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: $( "" ),
+ 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();
+ });
+ }
};
@@ -198,7 +170,7 @@ $( 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 = $("");
- 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 = $( "" );
+ 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 );
+
});
```
diff --git a/page/code-organization/deferreds.md b/page/code-organization/deferreds.md
index 5e10b597..5317fa53 100644
--- a/page/code-organization/deferreds.md
+++ b/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
- Addy Osmani
- Andree Hansson
@@ -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 */
});
```
diff --git a/page/code-organization/deferreds/examples.md b/page/code-organization/deferreds/examples.md
index 5ab68e62..31ddce78 100644
--- a/page/code-organization/deferreds/examples.md
+++ b/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
- Addy Osmani
- Andree Hansson
@@ -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,7 +258,7 @@ But let's define a helper method first:
```
$.fn.firstClick = function( callback ) {
- return this.bindOnce( "click", callback );
+ return this.bindOnce( "click", callback );
};
```
@@ -266,7 +266,7 @@ 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:
```
```
-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 = [];
+
+ $( "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();
+ });
});
```
-The trick here is to keep track of all the loadImage promises. We later
-join them with the panel slideDown animation using $.when. So when the
-button is first clicked, the panel will slideDown and the images will
+The trick here is to keep track of all the `loadImage` promises. We later
+join them with the panel `slideDown` animation using `$.when`. So when the
+button is first clicked, the panel will slide down and the images will
start loading. Once the panel has finished sliding down and all the
images have been loaded, then, and only then, will the panel fade in.
@@ -367,37 +366,36 @@ In order to implement deferred image display on the entire page,
the following format in HTML can be used.
```
-
-
-
-
+
+
+
+
```
What it says is pretty straight-forward:
-- load image1.png and show it immediately for the third image and
+- Load `image1.png` and show it immediately for the third image and
after one second for the first one
-- load image2.png and show it after one second for the second image
+- Load `image2.png` and show it after one second for the second image
and after two seconds for the fourth image
-
```
$( "img" ).each(function() {
- var element = $( this ),
- src = element.attr( "data-src" ),
- after = element.attr( "data-after" );
- if ( src ) {
- $.when(
- $.loadImage( src ),
- $.afterDOMReady( after )
- ).then(function() {
- element.attr( "src", src );
- }, function() {
- element.attr( "src", "error.png" );
- } ).done(function() {
- element.fadeIn();
- });
- }
+ var element = $( this ),
+ src = element.attr( "data-src" ),
+ after = element.attr( "data-after" );
+ if ( src ) {
+ $.when(
+ $.loadImage( src ),
+ $.afterDOMReady( after )
+ ).then(function() {
+ element.attr( "src", src );
+ }, function() {
+ element.attr( "src", "error.png" );
+ }).done(function() {
+ element.fadeIn();
+ });
+ }
});
```
@@ -405,20 +403,20 @@ In order to delay the loading of the images themselves:
```
$( "img" ).each(function() {
- var element = $( this ),
- src = element.attr( "data-src" ),
- after = element.attr( "data-after" );
- if ( src ) {
- $.afterDOMReady( after, function() {
- $.loadImage( src ).then(function() {
- element.attr( "src", src );
- }, function() {
- element.attr( "src", "error.png" );
- } ).done(function() {
- element.fadeIn();
- });
- } );
- }
+ var element = $( this ),
+ src = element.attr( "data-src" ),
+ after = element.attr( "data-after" );
+ if ( src ) {
+ $.afterDOMReady( after, function() {
+ $.loadImage( src ).then(function() {
+ element.attr( "src", src );
+ }, function() {
+ element.attr( "src", "error.png" );
+ }).done(function() {
+ element.fadeIn();
+ });
+ });
+ }
});
```
diff --git a/page/code-organization/deferreds/jquery-deferreds.md b/page/code-organization/deferreds/jquery-deferreds.md
index e37c5a19..9b59237e 100644
--- a/page/code-organization/deferreds/jquery-deferreds.md
+++ b/page/code-organization/deferreds/jquery-deferreds.md
@@ -2,7 +2,7 @@
title: jQuery Deferreds
level: advanced
source: http://msdn.microsoft.com/en-us/magazine/gg723713.aspx
-attribution:
+attribution:
- Julian Aubourg
- Addy Osmani
- Andree Hansson
@@ -11,10 +11,10 @@ attribution:
##jQuery Deferreds
Deferreds were added as a part of a large rewrite of the ajax module,
-led by Julian Auborg following the CommonJS Promises/A design. Whilst 1.5 and
+led by Julian Aubourg following the CommonJS Promises/A design. Whilst 1.5 and
above include deferred capabilities, former versions of jQuery had
-jQuery.ajax() accept callbacks that would be invoked upon completion or
-error of the request, but suffered from heavy coupling - the same
+`jQuery.ajax()` accept callbacks that would be invoked upon completion or
+error of the request, but suffered from heavy coupling — the same
principle that would drive developers using other languages or toolkits
to opt for deferred execution.
@@ -26,41 +26,41 @@ noting that jQuery's Deferred object supports having multiple callbacks
bound to the outcome of particular tasks (and not just one) where the
task itself can either be synchronous or asynchronous.
-At the heart of jQuery's implementation is jQuery.Deferred - a chainable
+At the heart of jQuery's implementation is `jQuery.Deferred` — a chainable
constructor which is able to create new deferred objects that can check
for the existence of a promise to establish whether the object can be
observed. It can also invoke callback queues and pass on the success of
synchronous and asynchronous functions. It's quite essential to note
-that the default state of any Deferred object is unresolved. Callbacks
-which may be added to it through .then() or .fail() are queued up and get
+that the default state of any Deferred object is unresolved. Callbacks
+which may be added to it through `.then()` or `.fail()` are queued up and get
executed later on in the process.
You are able to use Deferred objects in conjunction with the promise concept of
-when(), implemented in jQuery as $.when() to wait for all of the Deferred
-object's requests to complete executing (ie. for all of the promises to be
-fulfilled). In technical terms, $.when() is effectively a way to execute
+when(), implemented in jQuery as `$.when()` to wait for all of the Deferred
+object's requests to complete executing (i.e. for all of the promises to be
+fulfilled). In technical terms, `$.when()` is effectively a way to execute
callbacks based on any number of promises that represent asynchronous events.
-An example of $.when() accepting multiple arguments can be seen below in
-conjunction with .then():
+An example of `$.when()` accepting multiple arguments can be seen below in
+conjunction with `.then()`:
```
function successFunc(){
- console.log( "success!" );
-}
+ console.log( "success!" );
+}
function failureFunc(){
- console.log( "failure!" );
+ console.log( "failure!" );
}
$.when(
- $.ajax( "/main.php" ),
- $.ajax( "/modules.php" ),
- $.ajax( "/lists.php" )
+ $.ajax( "/main.php" ),
+ $.ajax( "/modules.php" ),
+ $.ajax( "/lists.php" )
).then( successFunc, failureFunc );
```
-The $.when() implementation offered in jQuery is quite interesting as it not
+The `$.when()` implementation offered in jQuery is quite interesting as it not
only interprets deferred objects, but when passed arguments that are not
deferreds, it treats these as if they were resolved deferreds and executes any
callbacks (doneCallbacks) right away. It is also worth noting that jQuery's
@@ -71,42 +71,41 @@ also be used to add callbacks to the deferred's queues.
We will now take a look at a code example that utilizes many of the deferred
features mentioned in the table presented earlier. Here is a very basic
application that consumes (1) an external news feed and (2) a reactions feed
-for pulling in the latest comments via $.get() (which will return a promise).
-The application also has a function (prepareInterface()) which returns a
+for pulling in the latest comments via `$.get()` (which will return a promise).
+The application also has a function (`prepareInterface()`) which returns a
promise to complete animating our containers for both the news and
reactions.
-
```
function getLatestNews() {
- return $.get( "latestNews.php", function(data){
- console.log( "news data received" );
- $( ".news" ).html(data);
- } );
+ return $.get( "latestNews.php", function( data ) {
+ console.log( "news data received" );
+ $( ".news" ).html( data );
+ });
}
function getLatestReactions() {
- return $.get( "latestReactions.php", function(data){
- console.log( "reactions data received" );
- $( ".reactions" ).html(data);
- } );
+ return $.get( "latestReactions.php", function( data ) {
+ console.log( "reactions data received" );
+ $( ".reactions" ).html( data );
+ });
}
function prepareInterface() {
- return $.Deferred(function( dfd ) {
- var latest = $( ".news, .reactions" );
- latest.slideDown( 500, dfd.resolve );
- latest.addClass( "active" );
- }).promise();
+ return $.Deferred(function( dfd ) {
+ var latest = $( ".news, .reactions" );
+ latest.slideDown( 500, dfd.resolve );
+ latest.addClass( "active" );
+ }).promise();
}
$.when(
- getLatestNews(),
- getLatestReactions(),
- prepareInterface()
+ getLatestNews(),
+ getLatestReactions(),
+ prepareInterface()
).then(function(){
- console.log( "fire after requests succeed" );
+ console.log( "fire after requests succeed" );
}).fail(function(){
- console.log( "something went wrong!" );
+ console.log( "something went wrong!" );
});
```
diff --git a/page/code-organization/dont-repeat-yourself.md b/page/code-organization/dont-repeat-yourself.md
index 320575dd..71881083 100644
--- a/page/code-organization/dont-repeat-yourself.md
+++ b/page/code-organization/dont-repeat-yourself.md
@@ -1,7 +1,7 @@
---
title: Keep Things DRY
level: beginner
-attribution:
+attribution:
source: http://jqfundamentals.com/legacy
- jQuery Fundamentals
---
@@ -9,34 +9,24 @@ Don't repeat yourself; if you're repeating yourself, you're doing it wrong.
```
// BAD
-if ( $eventfade.data("currently") !== "showing" ) {
-
- $eventfade.stop();
-
+if ( $eventfade.data( "currently" ) !== "showing" ) {
+ $eventfade.stop();
}
-if ( $eventhover.data("currently") !== "showing" ) {
-
- $eventhover.stop();
-
+if ( $eventhover.data( "currently" ) !== "showing" ) {
+ $eventhover.stop();
}
-if ( $spans.data("currently") !== "showing" ) {
-
- $spans.stop();
-
+if ( $spans.data( "currently" ) !== "showing" ) {
+ $spans.stop();
}
// GOOD!!
var $elems = [ $eventfade, $eventhover, $spans ];
$.each( $elems, function( i, elem ) {
-
- if ( elem.data("currently") !== "showing" ) {
-
- elem.stop();
-
- }
-
+ if ( elem.data( "currently" ) !== "showing" ) {
+ elem.stop();
+ }
});
```
diff --git a/page/code-organization/feature-browser-detection.md b/page/code-organization/feature-browser-detection.md
index 58f5d095..67d7040d 100644
--- a/page/code-organization/feature-browser-detection.md
+++ b/page/code-organization/feature-browser-detection.md
@@ -5,7 +5,7 @@ level: beginner
### Can I Use This Browser Feature?
-There are a couple of common ways to check whether or not a particular feature is supported by a user's browser:
+There are a couple of common ways to check whether or not a particular feature is supported by a user's browser:
* Browser Detection
* Specific Feature Detection
@@ -26,7 +26,7 @@ While this seems to be an easy solution, there are several problems:
#### Other browsers other than your target may have the same issue.
-If we target a specific browser for different functionality, we implicitly exclude any browser we did not account for. This is also not future-proof. If the browser we target receives a bug fix or change, we may not be able to discern between a 'working' and 'non-working' UA string. We may also need to update our test for each new release. This isn't a maintainable solution.
+If we target a specific browser for different functionality, we implicitly exclude any browser we did not account for. This is also not future-proof. If the browser we target receives a bug fix or change, we may not be able to discern between a "working" and "non-working" UA string. We may also need to update our test for each new release. This isn't a maintainable solution.
#### User Agents are unreliable.
@@ -51,7 +51,7 @@ Now how would you go about doing that?
There are several ways to go about feature detection:
* Straight JavaScript
-* $.support
+* `$.support`
* A Helper Library
#### Straight JavaScript
@@ -61,16 +61,12 @@ Let's take a look at how to check whether or not a `