Improve Your Web App with jQuery
Techniques
- Improve Performance
- Improve Accessibility
- Reduce Complexity
- Simplify Design
Improve Performance
- Event delegation
- Fragment caching
- CDNs and Gzipping
Event Delegation
- Event delegation is an efficient way to watch for an event on a large number of elements.
- Works by binding to a point farther up the DOM tree and watching for bubbling events.
- jQuery has two ways to do event delgation:
.live()
(as a direct replacement for .bind()) and .delegate()
.
- Works on all current, and future, elements.
.delegate()
$("table").delegate("td", "hover", function(){
$(this).toggleClass("active");
});
- Added the delegate (and undelegate) methods in jQuery 1.4.2.
- These allow you to easily listen for events from a particular context (the table, in this case).
Live Events
$("a.menu").live("hover", function(){
$(this).next().toggle(200);
return false;
});
Caching with Fragments
$("<li><a></a></li>");
- It can be expensive converting that HTML into DOM nodes.
- We can speed up inserting multiple versions if we cache the nodes.
- This is where document fragments really help (we use them in jQuery).
Document Fragments
var div = document.createElement("div");
div.innerHTML = "<li><a></a></li>";
var fragment = document.createDocumentFragment();
while ( div.firstChild ) {
fragment.appendChild( div.firstChild );
}
- A document fragment is just a lightweight container that can hold some DOM nodes.
- It makes it easy to store the nodes for later all while improving the performance of insertion.
Document Fragments
someDiv.appendChild( fragment ); // one operation!
- When you insert, or clone, a fragment all of its contents are automatically inserted or cloned.
- This ends up being really fast, avoid having to insert nodes one-by-one.
jQuery from a CDN
<script src='http://code.jquery.com/jquery.js'></script>
- jQuery, Google, and Microsoft all host jQuery on their CDNs.
- Automatically minified, gzipped, and geopositioned for performance.
Minified and Gzipped
- The best way to transfer JavaScript.
- Minification removes comments, whitespace, and makes other optimizations (Google Closure, YUIMin, and Packer).
- Gzipping that output compresses the filesize even further.
- jQuery goes from 150KB+ down to ~20KB.
Improve Accessibility
- Unobtrusive scripting
- Special Ajax loading
Unobtrusive Scripting
$("#somelink").click(function(){
return false; // stop the browser from visiting the link
});
- Turn a link or form that already works and layer on JavaScript enhancements.
- jQuery makes this behavior very simple when working with events.
- (No longer use non-functional links like '#' or 'javascript:void(0)'.)
Ready Event
$(document).ready(function(){
// Your jQuery code goes in here
});
- In order to traverse and manipulate the page we must wait until it's ready to be used.
- jQuery has a ready event that fires the instant the DOM is ready to be worked with.
- Stick all your jQuery code in a ready block, load it unobtrusively.
- No More Inline JavaScript!
Click and Load
$("a").click(function(){
$(this).next().load( this.href );
return false;
});
Extra Header
$_SERVER['HTTP_X_REQUESTED_WITH'];
- jQuery passes along an additional header that you can use to tailor your content.
- If the header exists, don't show the header/footer of the page to save bandwidth.
.load()
the contents right into your site!
.load() page fragment
$("div.load").load("file.html h2");
hello!
Reduce Complexity
- jQuery reduces complexity by providing element-centric ways to attach and transmit information.
- Data binding
- Event namespacing
- Custom events
Data Storage
$("div").data("test", 5);
$("div").data("test") === 5;
- jQuery has an API for invisibly storing data on DOM nodes.
- You can add data to any element (using .data) and we'll store it in a central repository.
Internal Data Storage
// Get all event handlers bound to an element
$("div").data("events");
- jQuery uses the data storage internally to keep track of all sorts of things.
- We store all the event handlers, toggling information, hide/show state, and various other bits.
Removing Data
// Remove all data bound to an element
$("div").removeData();
$("div").remove(); // also removes data
- Additionally, we'll manage all garbage collection, after the element has been removed.
Data Events
$("div").bind("getData.value", function(){
return myPlugin.realValue;
});
- We can also override the values retrieved or set on the data method by binding to getData and setData.
- Returning a value will set (or return) a completely different result.
- Very useful for plugins that want to override specific data behaviors.
Custom Events
$("div").bind("myplugin", someFn);
$("div").trigger("myplugin");
- You can bind to any event, there is no restriction on what you can or can't bind to.
- Naturally, some events are fired by the browser (click, focus, etc.)
- Everything else needs to be manually triggered.
Event Namespaces
$("div").bind("click.plugin", someFn);
$("div").bind("focus.plugin", otherFn);
$("div").unbind(".plugin");
- When you bind event handler you can also give them a namespace.
- This makes it easy to find later and easy to remove the handlers.
- Saves you from having to keep track of where all your functions are being bound, since you can just remove them by name.
Events and Plugins
$("div").bind("remove.pluginA", someFn);
$("div").bind("remove.pluginB", otherFn);
$("div").trigger("remove");
- As it turns out, custom events are a great way for multiple pieces of code (such as plugins) to bind to the same functionality.
- This creates a one to many relationship: You trigger one event but many handlers could be executed.
- This is a very efficient means of creating complex applications.
Special Events
- More complex than regular custom events (custom events don't interact with the browser).
- You can use special events to simulate other events.
- We use it for: submit, change, mouseenter, mouseleave, focusin, focusout.
- In 1.4.2 we added default special events (can be blocked with preventDefault).
Focusin/Focusout
if ( document.addEventListener ) {
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
jQuery.event.special[ fix ] = {
setup: function() {
this.addEventListener( orig, handler, true );
},
teardown: function() {
this.removeEventListener( orig, handler, true );
}
};
function handler( e ) {
e = jQuery.event.fix( e );
e.type = fix;
return jQuery.event.handle.call( this, e );
}
});
}
Hotkeys
$(document).bind("keydown", "ctrl+a", function(){
return false; // Prevent selecting all the text
});
jQuery UI
- A complete set of themed, cross-browser, user interface components.
- Drag, Drop, Sort, Select, Resize Accordion, Datepicker, Dialog, Slider, Tabs
- New in 1.8: Button, Autocomplete
- More info: http://jqueryui.com/
What are we working on?
- Ajax rewrite - much more extensible.
- Dynamic script loading and dependency management.
- Templating - make it easy to write templating plugins.
- Mobile support - we'll test against all the major mobile browsers and guarantee support.