SlideShare a Scribd company logo
1 of 78
Download to read offline
Secrets of
JavaScript Libraries
          (Left to Right)
    Sam Stephenson (Prototype)
        Alex Russell (Dojo)
   Thomas Fuchs (Script.aculo.us)
    Andrew Dupont (Prototype)
        John Resig (jQuery)
What to Cover
✦   Topics:
    ✦ JavaScript Language
    ✦ Cross-Browser Code
    ✦ Events
    ✦ DOM Traversal
    ✦ Style
    ✦ Animations
    ✦ Distribution
    ✦ HTML Insertion
Secrets of the
JavaScript Language
// Set up a class and create an element

var Clock = Class.create({
  initialize: function() {
     this.createElement();
  },

  createElement: function() {
    this.element = new Element(quot;divquot;);
  }
});
// Display the time

var Clock = Class.create({
  initialize: function() {
     this.createElement();
  },

  createElement: function() {
    this.element = new Element(quot;divquot;);

      var date = new Date();
      this.element.update(
         date.getHours() + quot;:quot; +
         date.getMinutes().toPaddedString(2) + quot;.quot; +
         date.getSeconds().toPaddedString(2)
      );
  }
});



$(document.body).insert(new Clock().element);
// Add the timer

var Clock = Class.create({
  initialize: function() {
     this.createElement();
     this.createTimer();
  },

  createElement: function() {
     this.element = new Element(quot;divquot;);
  },

  updateElement: function() {
     var date = new Date();
     this.element.update(
        date.getHours() + quot;:quot; +
        date.getMinutes().toPaddedString(2) + quot;.quot; +
        date.getSeconds().toPaddedString(2)
     );
  },

  createTimer: function() {
    window.setInterval(500, this.updateElement.bind(this));
  }
});
// Add some options

var Clock = Class.create({
  color: quot;blackquot;,
  format: quot;#{hour}:#{minute}.#{second}quot;,

 initialize: function(options) {
    Object.extend(this, options);
    this.createElement();
    this.createTimer();
 },

 createElement: function() {
    this.element = new Element(quot;divquot;);
    this.element.setStyle({ color: Clock().element);
      $(document.body).insert(new this.color });
 }, $(document.body).insert(new Clock({ color: quot;redquot; }).element);
      $(document.body).insert(new Clock({ format: quot;#{hour}:#{minute}quot; }).element);
 updateElement: function() {
    this.element.update(this.format.interpolate(this.getTime()));
 },

 getTime: function() {
   var date = new Date();
   return {
     hour:   date.getHours(),
     minute: date.getMinutes().toPaddedString(2),
     second: date.getSeconds().toPaddedString(2)
   }
 }, ...
// Use #toElement

var Clock = Class.create({
  ...

  toElement: function() {
    return this.element;
  }
});



$(document.body).insert(new Clock());
$(document.body).down(quot;div.clock > divquot;).replace(new Clock());
$(document.body).down(quot;div.clockquot;).update(new Clock());
// Subclass it

var AmPmClock = Class.create(Clock, {
  format: quot;#{hour}:#{minute}:#{second} #{ampm}quot;,

  getTime: function($super) {
    var time = $super();

      time.ampm = time.hour < 12 ? quot;amquot; : quot;pmquot;;

      if (time.hour == 0) {
        time.hour = 12;
      } else if (time.hour > 12) {
        time.hour -= 12;
      }

      return time;
  }
});

$(document.body).insert(new AmPmClock());
// Or monkeypatch it

Object.extend(Clock.prototype, {
  format: quot;#{hour}:#{minute}:#{second} #{ampm}quot;,

  getTime: Clock.prototype.getTime.wrap(function(original) {
    var time = original();

      time.ampm = time.hour < 12 ? quot;amquot; : quot;pmquot;;

      if (time.hour == 0) {
        time.hour = 12;
      } else if (time.hour > 12) {
        time.hour -= 12;
      }

      return time;
  }
});

$(document.body).insert(new Clock());
Secrets of
Cross-Browser Code
Browser Sniffing
    (wait, hear me out)
Conditionally evil
In order of desirability:
capabilities
    &
  quirks
Capabilities
  are easy to sniff
Quirks
are... more troublesome
Object detection
          (for capabilities)

 if (document.evaluate) {
   // ...
 }
Distill to a boolean
          (for stuff in the gray area)

var thinksCommentsAreElements = false;
if ( document.createElement('!') ) {
  thinksCommentsAreElements = true;
}
...then sniff
       (for outright bugs/quirks)

if (Prototype.Browser.IE) {
  element.style.filter =
   quot;alpha(opacity=50);quot;;
}
Try to do the right thing,
      but don’t stand on principle
The social contract
 Good faith from browser makers ➝
   good faith from web authors
Secrets
of Quality
Assurance
1,500




                          750




                          0
1.5.0
        1.5.1
                1.6.0.2
Debugging
✦   Localize & Reproduce
    ✦ Find the smallest possible code that
      generates the problem
✦   Easy test-case generation
    ✦ ./gen.sh 1245 ajax
      ./gen.sh 1246 dom
✦   Simple logging, all browsers:
    document.getElementById(“output”)
      .innerHTML += “<br>” + msg;
Secrets of
  Events
Event handlers
     are tricky
Don’t store them on the
     element itself
     circular references = sadness
Build a global hashtable
        (like jQuery does it)
Element Data Store
✦   Each element gets a unique ID
    (bound w/ a unique property)
    elem.jQuery12345 = 1;
✦   Points back to large data structure:
    data[1] = { ... all element data here ... };
✦   Data (like event handlers) are stored here
    data[1] = {
      handlers: { click: [ function(){...} ], ... }
    };
Then clean up
on page unload
 So that IE doesn’t keep them
  in memory in perpetuum
Fixing memory leaks
Internet Explorer 6
    red-headed stepchild
Don’t “prove” your code
     has no leaks
       (view the results!)
Drip
is awesome
Test page:
Create a bunch of elements, assign each an event
  handler, then remove each one from the page
Demonstrating the Leak
    Notice the stair-step effect
Plugging the leak
// In Prototype, will remove all event listeners from an element
Event.stopObserving(someElement);

Event.purgeObservers = function(element, includeParent) {
  Element.select(element, quot;*quot;).each(Event.stopObserving);
  if ( includeParent ) Event.stopObserving( element );
};
Redefining functions
   add “before advice” to functions
    that need to remove elements
Code sample
Element.Methods.update = Element.Methods.update.wrap(
  function(proceed, element, contents) {
    Event.purgeObservers(element);
    return proceed(element, contents);
  }
);

Element.Methods.replace = Element.Methods.replace.wrap(
  function(proceed, element, contents) {
    Event.purgeObservers(element, true);
    return proceed(element, contents);
  }
);

Element.Methods.remove = Element.Methods.remove.wrap(
  function(proceed, element) {
    Event.purgeObservers(element, true);
    return proceed(element);
  }
);

Element.addMethods();
Drop-in fix
for Prototype 1.6
Custom Events
• Everything is event based if you squint
• DOM is a good foundation
• Terrible for stitching together non-DOM
  components and code
• Composition == good, inheritance == bad
• Custom events let us join loosely
• When to use them? Pitfalls?
Custom Events (contd.)
// in Dojo:
dojo.subscribe(“/foo”, function(e, arg){ ... });
dojo.publish(“/foo”, [{ data: “thinger”}, “second arg”]);

// in Prototype:
document.observe(“event:foo”, function(e){ ... });
$(“nodeId”).fire(“event:foo”, { data: “thinger” });

// in jQuery:
$(document).bind(“foo”, function(e, data, arg){ ... });
$(document).trigger(“foo”, [{ data: “thinger”}, “second”]);
Secrets of
DOM Traversal
Selector Internals

• Optimized DOM
 • Top-down vs. bottom-up
 • Caching + winnowing
• XPath
• Native, aka: querySelectorAll()
Selector Internals
• Tradeoffs: size vs. speed vs. complexity
• Prototype: XPath when possible, else DOM
 • Good perf, lower complexity, hackable
• Dojo: all 3 methods, picks best available
 • Best perf, biggest, highest complexity
• JQuery: DOM
 • Good perf, small size, extensiblity vs.
    forward-compat tradeoff
Secrets of
  Style
Computed Style
✦   IE way vs. Everyone else
    ✦ IE returns “actual value”
    ✦ Everyone else returns “pixel value”
    ✦ font-size: 2em;
      IE: “2em”
      Other: 24
    ✦ Need to convert to common base

✦   Performance: Very costly, generally avoided
    wherever possible
Pixel Values in IE
✦   if ( !/^d+(px)?$/i.test( ret ) && /^d/.test( ret ) ) {
    	

 // Remember the original values
    	

 var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left;

    	

   // Put in the new values to get a computed value out
    	

   elem.runtimeStyle.left = elem.currentStyle.left;
    	

   elem.style.left = ret || 0;
    	

   ret = elem.style.pixelLeft + “px”;

    	

   // Revert the changed values
    	

   elem.style.left = style;
    	

   elem.runtimeStyle.left = runtimeStyle;
    }

✦   From Dean Edwards:
    http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
Computed Style
✦   Safari 2 & 3:
    Giant mess for display: none elements
    ✦ Safari 2
      ✦ getComputedStyle() returns undefined
    ✦ Safari 3
      ✦ Always return empty strings for value
      ✦ Much harder to detect
        var ret = document.defaultView.getComputedStyle( elem, null );
        return !ret || ret.getPropertyValue(”color”) == “”;
Finding dimensions
Dimensions of what?
  content box, border box, margin box...
DHTML properties
   clientWidth, offsetWidth
The value you want is not captured by any property



                Lorem ipsum dolor sit
                amet.




                            width

                          clientWidth

                         offsetWidth
Computed styles
 getting padding & border value
The fool-proof,
    painful way
           Take the offsetWidth,
then subtract computed padding & border
Code example
Element.getCSSWidth = function(element) {
  element = $(element);
  return element.offsetWidth -
   parseFloat(element.getStyle(quot;borderLeftquot;)) -
   parseFloat(element.getStyle(quot;paddingLeftquot;)) -
   parseFloat(element.getStyle(quot;paddingRightquot;)) -
   parseFloat(element.getStyle(quot;borderRightquot;));
};
Secrets
of Animation
Old-School
“Effects”
setInterval
Events-based
Secrets
ofJavaScript
Deployment
CONTENT
EXPIRATION
Concatenation
GZIP
4-5x smaller
Packaging
• Dev vs. deployment constraints
• No library a single file, but all ship that way
• # of requests largest constraint
 • Sync vs. async
 • Static resource servers + CDNs
• Dependency management matters!
 • Runtime vs. deployment
Packaging
// in Dojo:
dojo.provide(“foo.bar.Baz”);
dojo.require(“dojox.dtl”);

// in GWT:
package com.foo.bar;
import com.foo.bar.Blah;

// in JSAN:
JSAN.use(“foo.bar.Blah”);
// exports handled by build tools
Packaging

• The build-process divide
• Library support vs. server concat/shrink
• Can we strip “dead” code?
• Social artifacts of packaging systems
HTML Insertion
✦   $(“div”).append(“<b>foo</b>”);
✦   Convert HTML String
    ✦ innerHTML
    ✦ Range: .createContextualFragment()

✦   Must purify first:
    ✦ Fix <table>s for IE (<tbody> wrap)
    ✦ Handle <option>s (contain in <select>)
HTML Insertion
✦   // Fix “XHTML     ”-style tags in all browsers
    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 + “>”;
    });

✦   $(“<abbr/>”).html(“hello!”).appendTo(“#foo”);
Script Execution
✦   Execute Script in Global Scope

✦   var head = document.getElementsByTagName(”head”)[0] ||
    document.documentElement,
    	

 script = document.createElement(”script”);

    script.type = “text/javascript”;
    if ( jQuery.browser.msie )
    	

 script.text = data;
    else
    	

 script.appendChild( document.createTextNode( data ) );

    head.appendChild( script );
    head.removeChild( script );
Questions
✦   Panelists:
    ✦ John Resig (ejohn.org)
    ✦ Sam Stephenson (conio.net)
    ✦ Alex Russell (alex.dojotoolkit.org)
    ✦ Thomas Fuchs (script.aculo.us/thomas)
    ✦ Andrew Dupont (andrewdupont.net)

✦   Frameworks:
    ✦ Prototype (prototypejs.org)
    ✦ jQuery (jquery.com)
    ✦ Dojo (dojotoolkit.org)
    ✦ Script.aculo.us (script.aculo.us)

More Related Content

What's hot

What's hot (20)

Scalable JavaScript Design Patterns
Scalable JavaScript Design PatternsScalable JavaScript Design Patterns
Scalable JavaScript Design Patterns
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
JavaScript - From Birth To Closure
JavaScript - From Birth To ClosureJavaScript - From Birth To Closure
JavaScript - From Birth To Closure
 
JavaScript Best Pratices
JavaScript Best PraticesJavaScript Best Pratices
JavaScript Best Pratices
 
Javascript Module Patterns
Javascript Module PatternsJavascript Module Patterns
Javascript Module Patterns
 
How AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsHow AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design Patterns
 
The Theory Of The Dom
The Theory Of The DomThe Theory Of The Dom
The Theory Of The Dom
 
Java Script Best Practices
Java Script Best PracticesJava Script Best Practices
Java Script Best Practices
 
Javascript basics for automation testing
Javascript  basics for automation testingJavascript  basics for automation testing
Javascript basics for automation testing
 
Scalable JavaScript Application Architecture
Scalable JavaScript Application ArchitectureScalable JavaScript Application Architecture
Scalable JavaScript Application Architecture
 
JavaScript Library Overview
JavaScript Library OverviewJavaScript Library Overview
JavaScript Library Overview
 
Javascript
JavascriptJavascript
Javascript
 
From YUI3 to K2
From YUI3 to K2From YUI3 to K2
From YUI3 to K2
 
JavaScript 101
JavaScript 101JavaScript 101
JavaScript 101
 
Javascript Common Design Patterns
Javascript Common Design PatternsJavascript Common Design Patterns
Javascript Common Design Patterns
 
Design patterns in java script, jquery, angularjs
Design patterns in java script, jquery, angularjsDesign patterns in java script, jquery, angularjs
Design patterns in java script, jquery, angularjs
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]
 
JavaScript Patterns
JavaScript PatternsJavaScript Patterns
JavaScript Patterns
 
Paris Web - Javascript as a programming language
Paris Web - Javascript as a programming languageParis Web - Javascript as a programming language
Paris Web - Javascript as a programming language
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 

Viewers also liked (8)

Processing and Processing.js
Processing and Processing.jsProcessing and Processing.js
Processing and Processing.js
 
jQuery Internals + Cool Stuff
jQuery Internals + Cool StuffjQuery Internals + Cool Stuff
jQuery Internals + Cool Stuff
 
JavaScript Libraries (Kings of Code)
JavaScript Libraries (Kings of Code)JavaScript Libraries (Kings of Code)
JavaScript Libraries (Kings of Code)
 
JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)
 
Testing Mobile JavaScript (Fall 2010
Testing Mobile JavaScript (Fall 2010Testing Mobile JavaScript (Fall 2010
Testing Mobile JavaScript (Fall 2010
 
Khan Academy Computer Science
Khan Academy Computer ScienceKhan Academy Computer Science
Khan Academy Computer Science
 
Building a JavaScript Library
Building a JavaScript LibraryBuilding a JavaScript Library
Building a JavaScript Library
 
Understanding JavaScript Testing
Understanding JavaScript TestingUnderstanding JavaScript Testing
Understanding JavaScript Testing
 

Similar to Secrets of JavaScript Libraries

The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
rajivmordani
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
Andy Peterson
 
the next web now
the next web nowthe next web now
the next web now
zulin Gu
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
Jarod Ferguson
 

Similar to Secrets of JavaScript Libraries (20)

Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
 
DOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQueryDOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQuery
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
 
What's up with Prototype and script.aculo.us?
What's up with Prototype and script.aculo.us?What's up with Prototype and script.aculo.us?
What's up with Prototype and script.aculo.us?
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
Bubbles & Trees with jQuery
Bubbles & Trees with jQueryBubbles & Trees with jQuery
Bubbles & Trees with jQuery
 
Maintainable JavaScript 2011
Maintainable JavaScript 2011Maintainable JavaScript 2011
Maintainable JavaScript 2011
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
 
jQuery
jQueryjQuery
jQuery
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
the next web now
the next web nowthe next web now
the next web now
 
Building High Performance Web Applications and Sites
Building High Performance Web Applications and SitesBuilding High Performance Web Applications and Sites
Building High Performance Web Applications and Sites
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
Experience Manager 6 Developer Features - Highlights
Experience Manager 6 Developer Features - HighlightsExperience Manager 6 Developer Features - Highlights
Experience Manager 6 Developer Features - Highlights
 
Building Robust jQuery Plugins
Building Robust jQuery PluginsBuilding Robust jQuery Plugins
Building Robust jQuery Plugins
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
 
Javascript And J Query
Javascript And J QueryJavascript And J Query
Javascript And J Query
 

More from jeresig

Introduction to jQuery (Ajax Exp 2006)
Introduction to jQuery (Ajax Exp 2006)Introduction to jQuery (Ajax Exp 2006)
Introduction to jQuery (Ajax Exp 2006)
jeresig
 
jQuery Recommendations to the W3C (2011)
jQuery Recommendations to the W3C (2011)jQuery Recommendations to the W3C (2011)
jQuery Recommendations to the W3C (2011)
jeresig
 
jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (RIT 2011)jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (RIT 2011)
jeresig
 
jQuery Open Source Process (Knight Foundation 2011)
jQuery Open Source Process (Knight Foundation 2011)jQuery Open Source Process (Knight Foundation 2011)
jQuery Open Source Process (Knight Foundation 2011)
jeresig
 

More from jeresig (20)

Does Coding Every Day Matter?
Does Coding Every Day Matter?Does Coding Every Day Matter?
Does Coding Every Day Matter?
 
Accidentally Becoming a Digital Librarian
Accidentally Becoming a Digital LibrarianAccidentally Becoming a Digital Librarian
Accidentally Becoming a Digital Librarian
 
2014: John's Favorite Thing (Neo4j)
2014: John's Favorite Thing (Neo4j)2014: John's Favorite Thing (Neo4j)
2014: John's Favorite Thing (Neo4j)
 
Computer Vision as Art Historical Investigation
Computer Vision as Art Historical InvestigationComputer Vision as Art Historical Investigation
Computer Vision as Art Historical Investigation
 
Hacking Art History
Hacking Art HistoryHacking Art History
Hacking Art History
 
Using JS to teach JS at Khan Academy
Using JS to teach JS at Khan AcademyUsing JS to teach JS at Khan Academy
Using JS to teach JS at Khan Academy
 
Applying Computer Vision to Art History
Applying Computer Vision to Art HistoryApplying Computer Vision to Art History
Applying Computer Vision to Art History
 
NYARC 2014: Frick/Zeri Results
NYARC 2014: Frick/Zeri ResultsNYARC 2014: Frick/Zeri Results
NYARC 2014: Frick/Zeri Results
 
EmpireJS: Hacking Art with Node js and Image Analysis
EmpireJS: Hacking Art with Node js and Image AnalysisEmpireJS: Hacking Art with Node js and Image Analysis
EmpireJS: Hacking Art with Node js and Image Analysis
 
Applying Computer Vision to Art History
Applying Computer Vision to Art HistoryApplying Computer Vision to Art History
Applying Computer Vision to Art History
 
Introduction to jQuery (Ajax Exp 2006)
Introduction to jQuery (Ajax Exp 2006)Introduction to jQuery (Ajax Exp 2006)
Introduction to jQuery (Ajax Exp 2006)
 
jQuery Recommendations to the W3C (2011)
jQuery Recommendations to the W3C (2011)jQuery Recommendations to the W3C (2011)
jQuery Recommendations to the W3C (2011)
 
jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (RIT 2011)jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (RIT 2011)
 
jQuery Open Source Process (Knight Foundation 2011)
jQuery Open Source Process (Knight Foundation 2011)jQuery Open Source Process (Knight Foundation 2011)
jQuery Open Source Process (Knight Foundation 2011)
 
jQuery Mobile
jQuery MobilejQuery Mobile
jQuery Mobile
 
jQuery Open Source (Fronteer 2011)
jQuery Open Source (Fronteer 2011)jQuery Open Source (Fronteer 2011)
jQuery Open Source (Fronteer 2011)
 
Holistic JavaScript Performance
Holistic JavaScript PerformanceHolistic JavaScript Performance
Holistic JavaScript Performance
 
New Features Coming in Browsers (RIT '09)
New Features Coming in Browsers (RIT '09)New Features Coming in Browsers (RIT '09)
New Features Coming in Browsers (RIT '09)
 
Introduction to jQuery (Ajax Exp 2007)
Introduction to jQuery (Ajax Exp 2007)Introduction to jQuery (Ajax Exp 2007)
Introduction to jQuery (Ajax Exp 2007)
 
Advanced jQuery (Ajax Exp 2007)
Advanced jQuery (Ajax Exp 2007)Advanced jQuery (Ajax Exp 2007)
Advanced jQuery (Ajax Exp 2007)
 

Recently uploaded

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 

Recently uploaded (20)

04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 

Secrets of JavaScript Libraries

  • 1. Secrets of JavaScript Libraries (Left to Right) Sam Stephenson (Prototype) Alex Russell (Dojo) Thomas Fuchs (Script.aculo.us) Andrew Dupont (Prototype) John Resig (jQuery)
  • 2. What to Cover ✦ Topics: ✦ JavaScript Language ✦ Cross-Browser Code ✦ Events ✦ DOM Traversal ✦ Style ✦ Animations ✦ Distribution ✦ HTML Insertion
  • 4. // Set up a class and create an element var Clock = Class.create({ initialize: function() { this.createElement(); }, createElement: function() { this.element = new Element(quot;divquot;); } });
  • 5. // Display the time var Clock = Class.create({ initialize: function() { this.createElement(); }, createElement: function() { this.element = new Element(quot;divquot;); var date = new Date(); this.element.update( date.getHours() + quot;:quot; + date.getMinutes().toPaddedString(2) + quot;.quot; + date.getSeconds().toPaddedString(2) ); } }); $(document.body).insert(new Clock().element);
  • 6. // Add the timer var Clock = Class.create({ initialize: function() { this.createElement(); this.createTimer(); }, createElement: function() { this.element = new Element(quot;divquot;); }, updateElement: function() { var date = new Date(); this.element.update( date.getHours() + quot;:quot; + date.getMinutes().toPaddedString(2) + quot;.quot; + date.getSeconds().toPaddedString(2) ); }, createTimer: function() { window.setInterval(500, this.updateElement.bind(this)); } });
  • 7. // Add some options var Clock = Class.create({ color: quot;blackquot;, format: quot;#{hour}:#{minute}.#{second}quot;, initialize: function(options) { Object.extend(this, options); this.createElement(); this.createTimer(); }, createElement: function() { this.element = new Element(quot;divquot;); this.element.setStyle({ color: Clock().element); $(document.body).insert(new this.color }); }, $(document.body).insert(new Clock({ color: quot;redquot; }).element); $(document.body).insert(new Clock({ format: quot;#{hour}:#{minute}quot; }).element); updateElement: function() { this.element.update(this.format.interpolate(this.getTime())); }, getTime: function() { var date = new Date(); return { hour: date.getHours(), minute: date.getMinutes().toPaddedString(2), second: date.getSeconds().toPaddedString(2) } }, ...
  • 8. // Use #toElement var Clock = Class.create({ ... toElement: function() { return this.element; } }); $(document.body).insert(new Clock()); $(document.body).down(quot;div.clock > divquot;).replace(new Clock()); $(document.body).down(quot;div.clockquot;).update(new Clock());
  • 9. // Subclass it var AmPmClock = Class.create(Clock, { format: quot;#{hour}:#{minute}:#{second} #{ampm}quot;, getTime: function($super) { var time = $super(); time.ampm = time.hour < 12 ? quot;amquot; : quot;pmquot;; if (time.hour == 0) { time.hour = 12; } else if (time.hour > 12) { time.hour -= 12; } return time; } }); $(document.body).insert(new AmPmClock());
  • 10. // Or monkeypatch it Object.extend(Clock.prototype, { format: quot;#{hour}:#{minute}:#{second} #{ampm}quot;, getTime: Clock.prototype.getTime.wrap(function(original) { var time = original(); time.ampm = time.hour < 12 ? quot;amquot; : quot;pmquot;; if (time.hour == 0) { time.hour = 12; } else if (time.hour > 12) { time.hour -= 12; } return time; } }); $(document.body).insert(new Clock());
  • 12. Browser Sniffing (wait, hear me out)
  • 14. In order of desirability:
  • 15. capabilities & quirks
  • 16. Capabilities are easy to sniff
  • 18. Object detection (for capabilities) if (document.evaluate) { // ... }
  • 19. Distill to a boolean (for stuff in the gray area) var thinksCommentsAreElements = false; if ( document.createElement('!') ) { thinksCommentsAreElements = true; }
  • 20. ...then sniff (for outright bugs/quirks) if (Prototype.Browser.IE) { element.style.filter = quot;alpha(opacity=50);quot;; }
  • 21. Try to do the right thing, but don’t stand on principle
  • 22. The social contract Good faith from browser makers ➝ good faith from web authors
  • 24.
  • 25.
  • 26. 1,500 750 0 1.5.0 1.5.1 1.6.0.2
  • 27.
  • 28. Debugging ✦ Localize & Reproduce ✦ Find the smallest possible code that generates the problem ✦ Easy test-case generation ✦ ./gen.sh 1245 ajax ./gen.sh 1246 dom ✦ Simple logging, all browsers: document.getElementById(“output”) .innerHTML += “<br>” + msg;
  • 29. Secrets of Events
  • 30. Event handlers are tricky
  • 31. Don’t store them on the element itself circular references = sadness
  • 32. Build a global hashtable (like jQuery does it)
  • 33. Element Data Store ✦ Each element gets a unique ID (bound w/ a unique property) elem.jQuery12345 = 1; ✦ Points back to large data structure: data[1] = { ... all element data here ... }; ✦ Data (like event handlers) are stored here data[1] = { handlers: { click: [ function(){...} ], ... } };
  • 34. Then clean up on page unload So that IE doesn’t keep them in memory in perpetuum
  • 36. Internet Explorer 6 red-headed stepchild
  • 37. Don’t “prove” your code has no leaks (view the results!)
  • 39. Test page: Create a bunch of elements, assign each an event handler, then remove each one from the page
  • 40. Demonstrating the Leak Notice the stair-step effect
  • 41. Plugging the leak // In Prototype, will remove all event listeners from an element Event.stopObserving(someElement); Event.purgeObservers = function(element, includeParent) { Element.select(element, quot;*quot;).each(Event.stopObserving); if ( includeParent ) Event.stopObserving( element ); };
  • 42. Redefining functions add “before advice” to functions that need to remove elements
  • 43. Code sample Element.Methods.update = Element.Methods.update.wrap( function(proceed, element, contents) { Event.purgeObservers(element); return proceed(element, contents); } ); Element.Methods.replace = Element.Methods.replace.wrap( function(proceed, element, contents) { Event.purgeObservers(element, true); return proceed(element, contents); } ); Element.Methods.remove = Element.Methods.remove.wrap( function(proceed, element) { Event.purgeObservers(element, true); return proceed(element); } ); Element.addMethods();
  • 45. Custom Events • Everything is event based if you squint • DOM is a good foundation • Terrible for stitching together non-DOM components and code • Composition == good, inheritance == bad • Custom events let us join loosely • When to use them? Pitfalls?
  • 46. Custom Events (contd.) // in Dojo: dojo.subscribe(“/foo”, function(e, arg){ ... }); dojo.publish(“/foo”, [{ data: “thinger”}, “second arg”]); // in Prototype: document.observe(“event:foo”, function(e){ ... }); $(“nodeId”).fire(“event:foo”, { data: “thinger” }); // in jQuery: $(document).bind(“foo”, function(e, data, arg){ ... }); $(document).trigger(“foo”, [{ data: “thinger”}, “second”]);
  • 48. Selector Internals • Optimized DOM • Top-down vs. bottom-up • Caching + winnowing • XPath • Native, aka: querySelectorAll()
  • 49. Selector Internals • Tradeoffs: size vs. speed vs. complexity • Prototype: XPath when possible, else DOM • Good perf, lower complexity, hackable • Dojo: all 3 methods, picks best available • Best perf, biggest, highest complexity • JQuery: DOM • Good perf, small size, extensiblity vs. forward-compat tradeoff
  • 50. Secrets of Style
  • 51. Computed Style ✦ IE way vs. Everyone else ✦ IE returns “actual value” ✦ Everyone else returns “pixel value” ✦ font-size: 2em; IE: “2em” Other: 24 ✦ Need to convert to common base ✦ Performance: Very costly, generally avoided wherever possible
  • 52. Pixel Values in IE ✦ if ( !/^d+(px)?$/i.test( ret ) && /^d/.test( ret ) ) { // Remember the original values var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left; // Put in the new values to get a computed value out elem.runtimeStyle.left = elem.currentStyle.left; elem.style.left = ret || 0; ret = elem.style.pixelLeft + “px”; // Revert the changed values elem.style.left = style; elem.runtimeStyle.left = runtimeStyle; } ✦ From Dean Edwards: http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
  • 53. Computed Style ✦ Safari 2 & 3: Giant mess for display: none elements ✦ Safari 2 ✦ getComputedStyle() returns undefined ✦ Safari 3 ✦ Always return empty strings for value ✦ Much harder to detect var ret = document.defaultView.getComputedStyle( elem, null ); return !ret || ret.getPropertyValue(”color”) == “”;
  • 55. Dimensions of what? content box, border box, margin box...
  • 56. DHTML properties clientWidth, offsetWidth
  • 57. The value you want is not captured by any property Lorem ipsum dolor sit amet. width clientWidth offsetWidth
  • 58. Computed styles getting padding & border value
  • 59. The fool-proof, painful way Take the offsetWidth, then subtract computed padding & border
  • 60. Code example Element.getCSSWidth = function(element) { element = $(element); return element.offsetWidth - parseFloat(element.getStyle(quot;borderLeftquot;)) - parseFloat(element.getStyle(quot;paddingLeftquot;)) - parseFloat(element.getStyle(quot;paddingRightquot;)) - parseFloat(element.getStyle(quot;borderRightquot;)); };
  • 67.
  • 68.
  • 70.
  • 72. Packaging • Dev vs. deployment constraints • No library a single file, but all ship that way • # of requests largest constraint • Sync vs. async • Static resource servers + CDNs • Dependency management matters! • Runtime vs. deployment
  • 73. Packaging // in Dojo: dojo.provide(“foo.bar.Baz”); dojo.require(“dojox.dtl”); // in GWT: package com.foo.bar; import com.foo.bar.Blah; // in JSAN: JSAN.use(“foo.bar.Blah”); // exports handled by build tools
  • 74. Packaging • The build-process divide • Library support vs. server concat/shrink • Can we strip “dead” code? • Social artifacts of packaging systems
  • 75. HTML Insertion ✦ $(“div”).append(“<b>foo</b>”); ✦ Convert HTML String ✦ innerHTML ✦ Range: .createContextualFragment() ✦ Must purify first: ✦ Fix <table>s for IE (<tbody> wrap) ✦ Handle <option>s (contain in <select>)
  • 76. HTML Insertion ✦ // Fix “XHTML ”-style tags in all browsers 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 + “>”; }); ✦ $(“<abbr/>”).html(“hello!”).appendTo(“#foo”);
  • 77. Script Execution ✦ Execute Script in Global Scope ✦ var head = document.getElementsByTagName(”head”)[0] || document.documentElement, script = document.createElement(”script”); script.type = “text/javascript”; if ( jQuery.browser.msie ) script.text = data; else script.appendChild( document.createTextNode( data ) ); head.appendChild( script ); head.removeChild( script );
  • 78. Questions ✦ Panelists: ✦ John Resig (ejohn.org) ✦ Sam Stephenson (conio.net) ✦ Alex Russell (alex.dojotoolkit.org) ✦ Thomas Fuchs (script.aculo.us/thomas) ✦ Andrew Dupont (andrewdupont.net) ✦ Frameworks: ✦ Prototype (prototypejs.org) ✦ jQuery (jquery.com) ✦ Dojo (dojotoolkit.org) ✦ Script.aculo.us (script.aculo.us)