0% found this document useful (0 votes)
74 views37 pages

Jquery Internals + Cool Stuff: John Resig

This document discusses jQuery internals and provides an overview of key aspects including chaining, isolation, the jQuery wrapper, plugin wrapping, noConflict mode, element data, selectors, DOM manipulation, events, sniffing, testing, and profiling. It describes techniques like document fragments that improve DOM manipulation performance and how the Sizzle selector engine works.

Uploaded by

muhammadmubashir
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
74 views37 pages

Jquery Internals + Cool Stuff: John Resig

This document discusses jQuery internals and provides an overview of key aspects including chaining, isolation, the jQuery wrapper, plugin wrapping, noConflict mode, element data, selectors, DOM manipulation, events, sniffing, testing, and profiling. It describes techniques like document fragments that improve DOM manipulation performance and how the Sizzle selector engine works.

Uploaded by

muhammadmubashir
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 37

jQuery Internals

+ Cool Stuff
John Resig
http://ejohn.org/ - http://twitter.com/jeresig/
Overview
✦ Why we do what we do
✦ Features you may not know about
✦ New features coming
Parts of jQuery
✦ Common
✦ Selectors
✦ DOM Modification
✦ Events
✦ Sniffing
Chaining
✦ jQuery("<li><a></a></li>") // li
.find("a") // a
.attr("href", "http://ejohn.org/") // a
.html("John Resig") // a
.end() // li
.appendTo("ul");

✦ jQuery("<li><a></a></li>") // li
.find("a") // a
.attr("href", "http://ejohn.org/") // a
.html("John Resig") // a
.andSelf() // li, a
.addClass(“person”) // li, a
.end() // a
.end() // li
.appendTo("ul");
Isolation
✦ jQuery shouldn’t affect outside code
✦ We’re good at this

✦ Outside code shouldn’t effect jQuery


✦ Getting better at this
✦ (Still hurt by Object.prototype)
jQuery Wrapper
✦ (function(){
var jQuery = window.jQuery = function(){
// ...
};
})();
✦ (function(){
var foo = 5;

})();
Plugin Wrapping
✦ (function($){
// Your code...
})(jQuery);
✦ (function(){
var $ = jQuery;
// Your code...
})();
noConflict
✦ // Remove $
var $jq = jQuery.noConflict();
✦ // Remove $ and jQuery
jQuery.noConflict(true);
✦ Can even have multiple copies of jQuery
on the page, simultaneously
noConflict
✦ (function(){
var oldjQuery = window.jQuery;
var jQuery = window.jQuery = function(){
// ...
};
jQuery.noConflict = function(all){
if ( all )
window.jQuery = oldjQuery;
return jQuery;
};
})();
Element Data
✦ Added in jQuery 1.2
✦ Attaching data to elements can be
hazardous
✦ Store data:
jQuery.data(elem, “name”, “value”);
✦ Read data:
jQuery.data(elem, “name”);
✦ All data is stored in a central cache and
completely garbage collected, as necessary
Element Data (cont.)
✦ Added in jQuery 1.2.3
✦ Can handle namespacing
$(”div”).data(”test”, “original”);
$(”div”).data(”test.plugin”, “new data”);
$(”div”).data(”test”) == “original”; // true
$(”div”).data(”test.plugin”) == “new data”; // true
✦ Advanced data handling can be overridden
by plugins
$(element).bind(”setData.draggable”, function(event, key, value){
self.options[key] = value;
}).bind(”getData.draggable”, function(event, key){
return self.options[key];
});
Selectors
How It Works
✦ How it currently works
✦ “div > p”
✦ Find all divs
Loop through each div
✦ Find all child elements
✦ Verify if element is paragraph
How It Works
✦ “div p”
✦ Find all divs
Loop through all divs
✦ Find all p, relative to the div

✦ Merge all results


✦ Figure out unique results
Sizzle
✦ http://github.com/jeresig/sizzle/tree/master
✦ New Selector Engine for jQuery
✦ 1.5 - 4x faster than other libraries
✦ 4KB Compressed
✦ No dependencies, can be used by other
libraries (MochiKit, Prototype)
How Does it Work?
✦ Query Restructuring
✦ “div p”
✦ Find all p elements
For each p element
✦ check if parent is div
✦ if not, traverse up farther
✦ if at top, remove element
✦ if so, save element

✦ No merging! No unique!
How Does it Work?
✦ Faster for some queries, slower for others
✦ Depends on the DOM structure
✦ “div > p” much faster, for example
✦ Built like how browsers query the DOM
Niceties
✦ Query Caching
✦ if ( document.addEventListener && !document.querySelectorAll ) {
cache = {};
function invalidate(){ cache = {}; }
document.addEventListener("DOMAttrModified", invalidate, false);
document.addEventListener("DOMNodeInserted", invalidate, false);
document.addEventListener("DOMNodeRemoved", invalidate, false);
}

✦ Smart Fallbacks
✦ if ( document.getElementsByClassName ) {
Expr.order.splice(1, 0, "CLASS");
Expr.find.CLASS = function(match, context) {
return context.getElementsByClassName(match[1]);
};
}
Manipulation
✦ Four common methods:
append, prepend, before, after
✦ $(“<li>and this too!</li>”)
✦ How does it work?
3-step Process
✦ Cleaning the input
✦ Converting it into a DOM
✦ Injecting it into the DOM
Cleaning
✦ Make sure we’re working with HTML
input
✦ (Convert XML to HTML)
✦ <table/> -> <table></table>
✦ elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front,
tag){
return tag.match(/^(abbr|br|col|img|input|link|meta|param|
hr|area|embed)$/i) ?
all :
front + "></" + tag + ">";
});
Converting
✦ Inject HTML string using innerHTML
✦ var div = document.createElement(“div”);
div.innerHTML = html;
div.childNodes; // Your meat!
✦ But doesn’t work for all HTML
✦ <tr>, <td>, <option>, <legend> (+ others)
must be in correct container elements
✦ “<table><tbody>” + html + “</tbody></
table>”
Injecting
✦ var elems = div.childNodes;
✦ Loop through elems, cloneNode(true)
each, insert into DOM
✦ 5 paragraphs
✦ 100 divs
✦ 2 method calls (insert, clone)
✦ 1000 method

✦ *Very* slow
✦ Simple plugin provides 10-15x speed-up:
http://dev.jquery.com/~john/ticket/append/
Document Fragments
✦ No div.childNodes looping
✦ Move the nodes into a Document
Fragment
✦ Husk DOM container
✦ Whole container can be cloned
✦ and whole container can be injected
✦ Saves a ton of repetition
Events
Non-DOM Events
✦ function User(){}
✦ var user = new User();
✦ $(user).bind(“login”, function(){
alert(“all done”);
});

$(user).trigger(“login”);
Namespaced Events
✦ Added in jQuery 1.2
✦ Targeted adding and removal of events
✦ $(“div”).bind(“click.foo”, function(){
alert(“foo!”);
});
✦ Time to clean up!
$(“div”).unbind(“click.foo”);
✦ Added in jQuery 1.2.3:
$(“div”).unbind(“.foo”);
Special Events
✦ Added in jQuery 1.2.2
✦ Can create whole shadow event system
✦ New events: mouseenter, mouseleave,
mousewheel (w/ plugin), ready
✦ $(”li”).bind(”mouseenter”, function(){
$(this).addClass(”hover”);
}).bind(”mouseleave”, function(){
$(this).removeClass(”hover”);
});
Animations
✦ Full Animation plugin (in jQuery 1.2):
✦ jQuery.fx.step.corner = function(fx) {
fx.elem.style.top = fx.now + fx.unit;
fx.elem.style.left = fx.now + fx.unit;
};
✦ $(”#go”).click(function(){
$(”#block”).animate({corner: ‘40px’}, 500);
});
Sniffing
✦ All major JS libraries use browser sniffing
✦ Look at the user agent and make guesses
✦ We can get rid of this!
✦ Makes our code more resilient to change
Testing & Analysis
Testing
✦ Rapid testing
✦ ./gen.sh
#!/bin/sh
svn co https://jqueryjs.googlecode.com/svn/trunk/jquery $1
&> /dev/null
cp $2.html $1/index.html
cd $1
make &> /dev/null

✦ ./gen.sh 1234 dom


Test Suite
✦ qUnit (jQuery Test Suite)
http://docs.jquery.com/QUnit
✦ By Joern Zaefferer
qUnit Usage
✦ test("a basic test example", function() {
ok( true, "this test is fine" );
var value = "hello";
equals( "hello", value, "We expect value to be hello" );
});

module("Module A");
test("first test within module", function() {
ok( true, "all pass" );
});
test("second test within module", function() {
ok( true, "all pass" );
});

module("Module B");
test("some other test", function() {
expect(1);
ok( true, "well" );
});
qUnit Output
Profiling
✦ Deep Profiling Plugin
✦ Watch all method calls and events
✦ http://ejohn.org/blog/deep-profiling-
jquery-apps/
✦ http://dev.jquery.com/~john/plugins/profile/
github.com.html
✦ javascript:jQuery.displayProfile();
Thank You!
✦ John Resig
✦ http://ejohn.org/
✦ http://twitter.com/jeresig/

You might also like