37
jQuery Internals + Cool StuJohn Resig http://ejohn.org / - http://twitter.com/jeresig/

jQuery Internals + Cool Stuff

  • Upload
    jeresig

  • View
    35.122

  • Download
    0

Embed Size (px)

DESCRIPTION

Talk I gave at jQuery Conference '08 and Ajax Experience '08.

Citation preview

Page 1: jQuery Internals + Cool Stuff

jQuery Internals+ Cool Stuff

John Resighttp://ejohn.org/ - http://twitter.com/jeresig/

Page 2: jQuery Internals + Cool Stuff

Overview✦ Why we do what we do✦ Features you may not know about✦ New features coming

Page 3: jQuery Internals + Cool Stuff

Parts of jQuery✦ Common✦ Selectors✦ DOM Modification✦ Events✦ Sniffing

Page 4: jQuery Internals + Cool Stuff

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");

Page 5: jQuery Internals + Cool Stuff

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)

Page 6: jQuery Internals + Cool Stuff

jQuery Wrapper✦ (function(){

var jQuery = window.jQuery = function(){ // ... };})();

✦ (function(){ var foo = 5;

})();

Page 7: jQuery Internals + Cool Stuff

Plugin Wrapping✦ (function($){

// Your code...})(jQuery);

✦ (function(){ var $ = jQuery; // Your code...})();

Page 8: jQuery Internals + Cool Stuff

noConflict✦ // Remove $

var $jq = jQuery.noConflict();✦ // Remove $ and jQuery

jQuery.noConflict(true);✦ Can even have multiple copies of jQuery

on the page, simultaneously

Page 9: jQuery Internals + Cool Stuff

noConflict✦ (function(){

var oldjQuery = window.jQuery; var jQuery = window.jQuery = function(){ // ... }; jQuery.noConflict = function(all){ if ( all ) window.jQuery = oldjQuery; return jQuery; };})();

Page 10: jQuery Internals + Cool Stuff

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

Page 11: jQuery Internals + Cool Stuff

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];});

Page 12: jQuery Internals + Cool Stuff

Selectors

Page 13: jQuery Internals + Cool Stuff

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

Page 14: jQuery Internals + Cool Stuff

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

Page 15: jQuery Internals + Cool Stuff

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)

Page 16: jQuery Internals + Cool Stuff

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!

Page 17: jQuery Internals + Cool Stuff

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

Page 18: jQuery Internals + Cool Stuff

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]); };}

Page 19: jQuery Internals + Cool Stuff

Manipulation✦ Four common methods:

append, prepend, before, after✦ $(“<li>and this too!</li>”)✦ How does it work?

Page 20: jQuery Internals + Cool Stuff

3-step Process✦ Cleaning the input✦ Converting it into a DOM✦ Injecting it into the DOM

Page 21: jQuery Internals + Cool Stuff

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 + ">";});

Page 22: jQuery Internals + Cool Stuff

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>”

Page 23: jQuery Internals + Cool Stuff

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/

Page 24: jQuery Internals + Cool Stuff

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

Page 25: jQuery Internals + Cool Stuff

Events

Page 26: jQuery Internals + Cool Stuff

Non-DOM Events✦ function User(){}✦ var user = new User();✦ $(user).bind(“login”, function(){

alert(“all done”);});

$(user).trigger(“login”);

Page 27: jQuery Internals + Cool Stuff

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”);

Page 28: jQuery Internals + Cool Stuff

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”);});

Page 29: jQuery Internals + Cool Stuff

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);});

Page 30: jQuery Internals + Cool Stuff

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

Page 31: jQuery Internals + Cool Stuff

Testing & Analysis

Page 32: jQuery Internals + Cool Stuff

Testing✦ Rapid testing✦ ./gen.sh

#!/bin/shsvn co https://jqueryjs.googlecode.com/svn/trunk/jquery $1 &> /dev/nullcp $2.html $1/index.htmlcd $1make &> /dev/null

✦ ./gen.sh 1234 dom

Page 33: jQuery Internals + Cool Stuff

Test Suite✦ qUnit (jQuery Test Suite)

http://docs.jquery.com/QUnit✦ By Joern Zaefferer

Page 34: jQuery Internals + Cool Stuff

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" );});

Page 35: jQuery Internals + Cool Stuff

qUnit Output

Page 37: jQuery Internals + Cool Stuff

Thank You!✦ John Resig✦ http://ejohn.org/✦ http://twitter.com/jeresig/