Skip to content

moving /performance /faq /code-organization code examples to md #123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 15, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions page/code-organization/beware-anonymous-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ attribution: jQuery Fundamentals
Anonymous functions bound everywhere are a pain. They're difficult to debug,
maintain, test, or reuse. Instead, use an object literal to organize and name
your handlers and callbacks.
<javascript>
```
// BAD
$(document).ready(function() {
$('#magic').click(function(e) {
Expand Down Expand Up @@ -37,4 +37,4 @@ var PI = {
};

$(document).ready(PI.onReady);
</javascript>
```
27 changes: 15 additions & 12 deletions page/code-organization/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ some concepts that are common to all good code organization patterns.
- Despite jQuery's DOM-centric nature, JavaScript applications are not all
about the DOM. Remember that not all pieces of functionality need to — or
should — have a DOM representation.
- Units of functionality should be [loosely coupled](http://en.wikipedia.org/wiki/Loose_coupling), that is,
- Units of functionality should be [loosely coupled](http://en.wikipedia.org/wiki/Loose_coupling), that is,
a unit of functionality should be able to exist on its own, and communication between
units should be handled via a messaging system such as custom events or
pub/sub. Stay away from direct communication between units of functionality
Expand All @@ -45,7 +45,8 @@ doesn't offer any privacy for properties or methods, but it's useful for
eliminating anonymous functions from your code, centralizing configuration
options, and easing the path to reuse and refactoring.

<javascript caption="An object literal">
```
// An object literal
var myFeature = {
myProperty : 'hello',

Expand All @@ -66,7 +67,7 @@ options, and easing the path to reuse and refactoring.
myFeature.myMethod(); // logs 'hello'
myFeature.init({ foo : 'bar' });
myFeature.readSettings(); // logs { foo : 'bar' }
</javascript>
```

The object literal above is simply an object assigned to a variable. The object
has one property and several methods. All of the properties and methods are
Expand All @@ -77,7 +78,7 @@ be called before the object is functional.
How would we apply this pattern to jQuery code? Let's say that we had this code
written in the traditional jQuery style:

<javascript>
```
// clicking on a list item loads some content
// using the list item's ID and hides content
// in sibling list items
Expand All @@ -97,7 +98,7 @@ written in the traditional jQuery style:
);
});
});
</javascript>
```

If this were the extent of our application, leaving it as-is would be fine. On
the other hand, if this was a piece of a larger application, we'd do well to
Expand All @@ -106,7 +107,8 @@ want to move the URL out of the code and into a configuration area. Finally, we
might want to break up the chain to make it easier to modify pieces of the
functionality later.

<javascript caption="Using an object literal for a jQuery feature">
```
// Using an object literal for a jQuery feature
var myFeature = {
init : function(settings) {
myFeature.config = {
Expand Down Expand Up @@ -166,7 +168,7 @@ functionality later.
};

$(document).ready(myFeature.init);
</javascript>
```

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
Expand Down Expand Up @@ -194,8 +196,8 @@ The module pattern overcomes some of the limitations of the object literal,
offering privacy for variables and functions while exposing a public API if
desired.

<javascript caption="The module pattern">

```
// The module pattern
var feature =(function() {

// private variables and functions
Expand Down Expand Up @@ -224,7 +226,7 @@ desired.
feature.sayPrivateThing();
// logs 'secret' and changes the value
// of privateThing
</javascript>
```

In the example above, we self-execute an anonymous function that returns an
object. Inside of the function, we define some variables. Because the variables
Expand All @@ -243,7 +245,8 @@ Below is a revised version of the previous example, showing how we could create
the same feature using the module pattern while only exposing one public method
of the module, `showItemByIndex()`.

<javascript caption="Using the module pattern for a jQuery feature">
```
// Using the module pattern for a jQuery feature
$(document).ready(function() {
var feature = (function() {
var $items = $('#myFeature li'),
Expand Down Expand Up @@ -297,4 +300,4 @@ of the module, `showItemByIndex()`.

feature.showItemByIndex(0);
});
</javascript>
```
4 changes: 2 additions & 2 deletions page/code-organization/dont-repeat-yourself.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ attribution: jQuery Fundamentals
---
Don't repeat yourself; if you're repeating yourself, you're doing it wrong.

<javascript>
```
// BAD
if ($eventfade.data('currently') != 'showing') {
$eventfade.stop();
Expand All @@ -25,4 +25,4 @@ $.each($elems, function(i,elem) {
elem.stop();
}
});
</javascript>
```
38 changes: 19 additions & 19 deletions page/faq/add_keyboard_navigation.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Adding Keyboard Navigation
attribution: Remy Sharp
attribution: Remy Sharp
status: needswork
editrequired: 2
source: http://jqueryfordesigners.com/adding-keyboard-navigation/
Expand Down Expand Up @@ -34,17 +34,17 @@ Then a keyboard key is pressed the event break into three separate events, which

So I’m going to use the last phase of the events and use the keyup event.

<div class="example" markdown="1">
```
$(document.documentElement).keyup(function (event) {
// handle cursor keys
});
</div>
```

Note that all event handlers in jQuery, such as click, keyup, mouseover, etc receive an event [argument](http://en.wikipedia.org/wiki/Parameter_(computer_science)) - which I’ve captured under the variable name event.

The left and right key codes are 37 and 39 respectively. So we only want to action the slide if these keys are pressed, so we’ll check the keyCode property on the event - this property is [very well supported in browsers](http://www.quirksmode.org/js/keys.html):

<div class="example" markdown="1">
```
$(document.documentElement).keyup(function (event) {
// handle cursor keys
if (event.keyCode == 37) {
Expand All @@ -53,15 +53,15 @@ The left and right key codes are 37 and 39 respectively. So we only want to acti
// go right
}
});
</div>
```

##Triggering the Click on the Right Link

Triggering a click event is easy, but the problem we have to solve is finding the right link to click. Since this slider adds a class of current to the currently active link, we’ll use that as our anchor point, and try to find the link before (if the left cursor key is pressed) and after (if the right cursor key is pressed).

In some cases the current class might be on list element, which would make the navigating slightly easier, but in this case the markup looks a bit like this:

<div class="example" markdown="1">
```
&lt;div class="coda-slider-wrapper"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="current" href="#1"&gt;1&lt;/a&gt;&lt;/li&gt;
Expand All @@ -71,31 +71,31 @@ In some cases the current class might be on list element, which would make the n
&lt;li&gt;&lt;a href="#5"&gt;5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</div>
```

In the case above, the “next” link is #2. Currently there’s no previous available, but we’ll let jQuery handle this for us.

To find the next link, first we need to grab the link that’s currently selected:

<div class="example" markdown="1">
```
$('.coda-slider-wrapper ul a.current')
</div>
```

Next we need to move up the tree (to the li element) and move to the next element and then back down to the a element to trigger a click.

<div class="example" markdown="1">
```
$('.coda-slider-wrapper ul a.current')
.parent() // moves up to the li element
.next() // moves to the adjacent li element
.find('a') // moves down to the link
.click(); // triggers a click on the next link
</div>
```

Since jQuery continues to allow chained methods to work even if there’s no elements found, we can also use prev() in the place of next() when current is on the first element and the code will work just fine still.

Let’s plug this code in to the keyboard event handler:

<div class="example" markdown="1">
```
$(document.documentElement).keyup(function (event) {
// handle cursor keys
if (event.keyCode == 37) {
Expand All @@ -111,11 +111,11 @@ Let’s plug this code in to the keyboard event handler:
$('.coda-slider-wrapper ul a.current').parent().next().find('a').click();
}
});
</div>
```

This code can be simplified since a lot of it is repetitive aside from the ‘next’ and ‘prev’. If you’re happy for slightly more complicated code, then use the code below, otherwise stick with the code above.

<div class="example" markdown="1">
```
$(document.documentElement).keyup(function (event) {
var direction = null;

Expand All @@ -132,7 +132,7 @@ This code can be simplified since a lot of it is repetitive aside from the ‘ne
$('.coda-slider-wrapper ul a.current').parent()[direction]().find('a').click();
}
});
</div>
```

##Where does this all go?

Expand All @@ -142,15 +142,15 @@ Since we’re going in after the slider plugin is run, so it should go *directly

In Mathieu’s code, he had the following:

<div class="example" markdown="1">
```
$().ready(function() {
$('#coda-slider-1').codaSlider();
});
</div>
```

Note that $().ready is the same as $(document).ready (though it’s not a style I would personally use). *Directly* after the plugin (i.e. before the });) results in the following code:

<div class="example" markdown="1">
```
$().ready(function() {
$().ready(function() {
$('#coda-slider-1').codaSlider();
Expand All @@ -172,7 +172,7 @@ $().ready(function() {
}
});
});
</div>
```

You can see this all [in action in the demo](http://static.jqueryfordesigners.com/demo/keyboard-nav.html), and be sure to use the left and right keyboard cursor keys to see the demo working.

Expand Down
16 changes: 8 additions & 8 deletions page/faq/enable_the_back_button.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,23 @@ This process was our original code, and most of it needs to stay in place. The c

So we listen for the hashchange event, just like we might listen for a click event:

<div class="example" markdown="1">
```
$(window).bind('hashchange', function(){
//do some magic
});
</div>
```

Now we move all of the original code from the click handler in to this new event listener. I’ve copied this code in, and marked in bold which lines we’ll need to change:

<div class="example" markdown="1">
```
$(window).bind('hashchange', function(){
tabContainers.hide();
tabContainers.filter(this.hash).show();
$('div.tabs ul.tabNavigation a').removeClass('selected');
$(this).addClass('selected');
return false;
});
</div>
```

At this point all the references to this need to change, because in our original version this referred to the link that had be clicked. Now we need to determine the link based on the window URL. We can get the newly navigated URL using window.location. This is an object that represents part of the URL, and as such, gives as just the hash by itself:window.location.hash. This is good.

Expand All @@ -60,9 +60,9 @@ Next we need to address how we can target the appropriate tab to add the selecte

Since we don’t have this to target the right tab, we need to find the element using jQuery. Since we have the hash, we can use this to find the tab link. We can use the “hash” attribute selector like this:

<div class="example" markdown="1">
```
$('a[hash=#first]')
</div>
```

Therefore we can substitute our hash variable in to the ‘#first’ part of the selector above, and now we’ll have the right element to add the selected class.

Expand All @@ -74,7 +74,7 @@ Then one last change to make to our code - we need to trigger the hashchange eve

Our final code looks like this:

<div class="example" markdown="1">
```
$(function() {
var tabContainers = $('div.tabs > div');
tabContainers.hide().filter(':first').show();
Expand All @@ -89,6 +89,6 @@ $(window).bind('hashchange', function(){

$(window).trigger("hashchange");
});
</div>
```

Once last note: if we trigger the hashchange event, and there’s no hash on the URL, then we need to give it a default. In this case I’ve given it #first as a default so that it always lands on the first tab if there’s nothing pre-selected.
12 changes: 6 additions & 6 deletions page/performance/append-outside-loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ tags: performance
Touching the DOM comes at a cost; if you're appending a lot of elements to the
DOM, you will want to append them all at once, rather then one at a time. This is common problem when appending elements within a loop.

<javascript>
```
$.each(myArray, function(i, item) {
var newListItem = '<li>' + item + '</li>';
$('#ballers').append(newListItem);
});
</javascript>
```

One common technique is to leverage a document fragment. During each iteration
of the loop, you append the element to the fragment rather than the DOM
element. After the loop, just append the fragment to the DOM element.

<javascript>
```
var frag = document.createDocumentFragment();

$.each(myArray, function (i, item) {
Expand All @@ -29,18 +29,18 @@ $.each(myArray, function (i, item) {
});

$('#ballers')[0].appendChild(frag);
</javascript>
```

Another technique, which is quite simple, is to build up a string during each iteration of the loop. After the loop, just set the html of the DOM element to that string.

<javascript>
```
var myHtml = '';

$.each(myArray, function(i, item) {
myHtml += '<li>' + item + '</li>';
});

$('#ballers').html(myHtml);
</javascript>
```

There are of course other techniques you could certainly test out; a great way to test the performance of these is through a site called [jsperf](http://jsperf.com). This site allows you to benchmark each technique and visually see how it performs across all the browsers.
5 changes: 3 additions & 2 deletions page/performance/cache-loop-length.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ tags: performance

In a for loop, don't access the length property of an array every time; cache
it beforehand.
<javascript>

```
var myLength = myArray.length;

for (var i = 0; i < myLength; i++) {
// do stuff
}
</javascript>
```
Loading