SlideShare a Scribd company logo
1 of 81
Download to read offline
Your JS Library
                       Dan Webb AKA @danwrong




Tuesday, May 3, 2011
Tuesday, May 3, 2011
In the beginning...




Tuesday, May 3, 2011
In the beginning...




Tuesday, May 3, 2011
$("p.surprise").addClass("ohmy").show("slow");




Tuesday, May 3, 2011
We all know what
                       happened next...
                                      jQuery




                                      The Rest


Tuesday, May 3, 2011
Why?



Tuesday, May 3, 2011
Internals were not
                       important...


Tuesday, May 3, 2011
...what had John created
                       was a great interface


Tuesday, May 3, 2011
"All programmers are
                                     API designers"
                       Joshua Bloch (http://lcsd05.cs.tamu.edu/slides/keynote.pdf)




Tuesday, May 3, 2011
The API is priority #1



Tuesday, May 3, 2011
❖ Predictability
                       ❖ Simplicity
                       ❖ Flexibility

Tuesday, May 3, 2011
Predictability



Tuesday, May 3, 2011
Tuesday, May 3, 2011
                       RTFM
Short attention span
Tuesday, May 3, 2011
Think about your
                       audience...


Tuesday, May 3, 2011
...use conventions people
                       already know


Tuesday, May 3, 2011
Language conventions
                       and standard library


Tuesday, May 3, 2011
THIS IS JAVASCRIPT


Tuesday, May 3, 2011
useCamelCase, yesReally.



Tuesday, May 3, 2011
Be careful with polyfills



Tuesday, May 3, 2011
Popular JS libraries



Tuesday, May 3, 2011
var paper = Raphael(10, 50, 320, 200);

                       var c = paper.circle(50, 40, 10);

                       c.attr("fill", "#f00");

                       c.show();




Tuesday, May 3, 2011
The problem domain



Tuesday, May 3, 2011
a.internal {
                         color: #44e534;
                         text-decoration: none;
                       }

                       $('a.external').css({
                         color: '#44e534',
                         textDecoration: 'none'
                       });

Tuesday, May 3, 2011
Example: creating a
                       DOM Builder


Tuesday, May 3, 2011
node.innerHTML = '<form method="post" action="/action">' +
                                          '<p>' +
                                            '<label>' +
                                              'Username: <input type="text" name="username">' +
                                            '</label>' +
                                            '<label>' +
                                              'Password: <input type="password" name="password">' +
                                            '</label>' +
                                          '</p>' +
                                        '</form>';

                       var form = document.createElement('form');
                       var p = document.createElement('p');
                       form.setAttribute('action', '/login');
                       form.setAttribute('method', 'post');
                       var usernameLabel = document.createElement('label');
                       var usernameText = document.createTextElement('Username: ');
                       var usernameInput = document.createElement('input');
                       usernameInput.setAttribute('type', 'text');
                       usernameInput.setAttribute('name', 'username');
                       form.appendChild(p);
                       p.appendChild(usernameLabel);
                       // ... at this point I decided to give
                       // all this up and become a farmer




Tuesday, May 3, 2011
var html = {
                         element: function(name, attributes, children) {
                           var node = document.createElement(name);

                               for (var attr in attributes) {
                                 node.setAttribute(attr, attributes[attr]);
                               }

                               for (var i=0, len=children.length; i < len; i++) {
                                 node.appendChild(children[i]);
                               }

                               return node;
                           }
                       }




Tuesday, May 3, 2011
var form = html.element(
                          'form',
                          { action: '/login', method: 'post' }
                          [
                            html.element('p', {}, [
                               html.element('label', {}, [
                                  document.createTextElement('Username: '),
                                  html.element('input', { type: 'text', name: 'username' }, []),
                                  // ... you get the idea
                               ])
                            ])
                          ]
                       );




Tuesday, May 3, 2011
var form = html.form({ action: '/login', method: 'post' },
                          [
                            html.p({}, [
                               html.label({}, [
                                  document.createTextElement('Username: '),
                                  html.input({ type: 'text', name: 'username' }, []),
                                  // ... you still get the idea, right?
                               ])
                            ])
                          ]
                       );




Tuesday, May 3, 2011
function elementBuilder(name) {
                         return function(attributes, children) {
                           return html.element(name, attributes, children);
                         }
                       }

                       function generateBuilderFunctions(elements) {
                         for (var i=0, len=elements.length; i < len; i++) {
                           html[elements[i]] = createElementBuilder(elements[i]);
                         }
                       }

                       generateBuilderFunctions("p|div|span|strong|em|img|table|tr|
                       td|th|thead|tbody|tfoot|pre|code|h1|h2|h3|h4|h5|h6|ul|ol|li|
                       form|input|textarea|legend|fieldset|select|option|
                       blockquote|cite|br|hr|dd|dl|dt|address|a|button|abbr|
                       acronym|script|link|style|bdo|ins|del|object|param|col|
                       colgroup|optgroup|caption|label|dfn|kbd|samp|var".split
                       ("|"));



Tuesday, May 3, 2011
Simplicity



Tuesday, May 3, 2011
Tuesday, May 3, 2011
Don’t make me
                       RTFM again...


Tuesday, May 3, 2011
Sensible defaults



Tuesday, May 3, 2011
Tuesday, May 3, 2011
Tuesday, May 3, 2011
var evt = document.createEvent("MouseEvents");

                       evt.initMouseEvent("click", true, true, window,
                                          0, 0, 0, 0, 0, false, false,
                                          false, false, 0, null);




Tuesday, May 3, 2011
element.addEventListener('input', function() {
                         // do some front-end magic
                       }, false);




Tuesday, May 3, 2011
var evt = document.createEvent("MouseEvents");

                       evt.initMouseEvent("click", true, true, window,
                                          0, 0, 0, 0, 0, false, false,
                                          false, false, 0, null);




Tuesday, May 3, 2011
Use options hashes for
                       optional arguments


Tuesday, May 3, 2011
evt.initMouseEvent("click", {
                         bubble: false,
                         relatedTarget: thing
                       });




Tuesday, May 3, 2011
http://blog.rebeccamurphey.com/objects-as-
                       arguments-in-javascript-where-do-y




Tuesday, May 3, 2011
Function calls
                       should read well


Tuesday, May 3, 2011
// replace oldNode with newNode - DOM API
                       oldNode.parentNode.replaceChild(newNode, oldNode);

                       // Dojo
                       dojo.place(newNode, oldNode, "replace");

                       // jQuery
                       $(oldNode).replaceWith(newNode);




Tuesday, May 3, 2011
Mask complexity if
                       possible


Tuesday, May 3, 2011
var con = xd.connect({ src: 'http://danwebb.net/receiver' });

                       con.bind('ready', function() {
                         rpc(con).call('getData', function(result) {
                           alert(result);
                         });
                       });




Tuesday, May 3, 2011
xd.connect({ src: 'http://danwebb.net/receiver' }, function(con) {
                         rpc(con).call('getData', function(result) {
                           alert(result);
                         });
                       });




Tuesday, May 3, 2011
var con = xd.connect({ src: 'http://danwebb.net/receiver' });

                       rpc(con).call('getData', function(result) {
                         alert(result);
                       });




Tuesday, May 3, 2011
Back to the DOM Builder



Tuesday, May 3, 2011
var form = html.form({ action: '/login', method: 'post' },
                          [
                            html.p({}, [
                               html.label({}, [
                                  document.createTextElement('Username: '),
                                  html.input({ type: 'text', name: 'username' }, []),
                                  // ... you still get the idea, right?
                               ])
                            ])
                          ]
                       );




Tuesday, May 3, 2011
var form = html.form({ method: 'post', action: '/login' },
                          html.p(
                            html.label(
                               'Username: ',
                               html.input({ type: 'text', name: 'username' })
                            ),
                            html.label(
                               'Password: ',
                               html.input({ type: 'password', name: 'pass' })
                            ),
                            html.input({ type: 'submit', value: 'Login'})
                          )
                       );




Tuesday, May 3, 2011
function elementBuilder(name) {
                         return function() {
                           var attributes = {}, children = [],
                               args = Array.prototype.slice.call(arguments);

                               // if the first arg is not a element or a string then its an attributes hash
                               if (!args[0].nodeType && typeof args[0] != 'string') {
                                 attributes = args.unshift();
                               }

                               // children can be an array or remaining args
                               if (Array.isArray(args[0])) {
                                 args = args[0];
                               }

                               // add rest of args as children converting any strings to text nodes
                               for (var i=0, len=args.length; i < len; i++) {
                                 if (typeof args[i] == 'string') {
                                   children.push(document.createTextNode(args[i]));
                                 } else {
                                   children.push(args[i]);
                                 }
                               }

                               return html.element(name, attributes, children);
                           }
                       }




Tuesday, May 3, 2011
Flexibility



Tuesday, May 3, 2011
Tuesday, May 3, 2011
Tuesday, May 3, 2011
Tuesday, May 3, 2011
Remember: you can't
                       please everyone


Tuesday, May 3, 2011
Don’t try to second
                       guess every use case


Tuesday, May 3, 2011
Options hashes != flexibility



Tuesday, May 3, 2011
28 options!
Tuesday, May 3, 2011
Add hackability


Tuesday, May 3, 2011
public, internal, protected



Tuesday, May 3, 2011
var lib = (function() {
                         var private = function() {
                            // you can't mess with me
                         };

                         return {
                           _internal: function() {
                              // you probably shouldn't mess with me
                           },
                           public: function() {
                              // I'm part of the API - call me sometime
                           }
                         }
                       }());



Tuesday, May 3, 2011
...using functions


Tuesday, May 3, 2011
// https://github.com/ender-js/Ender

                       $._select = function(selector, root) {
                         return Sizzle(selector, root);
                       }

                       $._select = function (selector, root) {
                         return (root || document).querySelectorAll(selector);
                       });




Tuesday, May 3, 2011
..inheritance


Tuesday, May 3, 2011
// github.com/danwrong/loadrunner

                       function Mustache(path) {
                         this.path = path;
                       }
                       Mustache.prototype = new loadrunner.Dependency;
                       Mustache.prototype.start = function() {
                         var me = this;

                           $.get(this.path, function(result) {
                             var template = Mustache.parse(result);
                             me.complete(template);
                           });
                       }

                       using(new Mustache('thing.mustache'), function(template) {
                         template.evaluate({ a: 'yep', b: 'nope' });
                       });



Tuesday, May 3, 2011
..duck typing



Tuesday, May 3, 2011
Meanwhile, back in
                       DOM Builder land...


Tuesday, May 3, 2011
function elementBuilder(name) {
                         return function() {
                           // code collapsed for clarity

                               // add rest of args as children
                               // converting any strings to text nodes
                               for (var i=0, len=args.length; i < len; i++) {
                                 if (typeof args[i] == 'string') {
                                   node = document.createTextNode(args[i]);
                                 } else {
                                   if (typeof args[i].toDOM == 'function') {
                                     node = args[i].toDOM();
                                   } else {
                                     node = args[i];
                                   }
                                 }

                                   children.push(node);
                               }

                               return html.element(name, attributes, children);
                           }
                       }



Tuesday, May 3, 2011
function Tweet(text, author, timestamp) {
                         this.text = text;
                         this.author = author;
                         this.timestamp = timestamp;
                       }
                       Tweet.prototype.toDOM = function() {
                         return html.p(
                            { 'class': 'tweet' },
                            html.strong(this.author.name),
                            this.text,
                            html.span({ 'class': 'time' }, this.timestamp)
                         );
                       }

                       var timeline = // an array of Tweet objects

                       document.appendChild(html.div({ id: 'timeline' }, timeline));




Tuesday, May 3, 2011
Create a framework for
                       solving your problem...


Tuesday, May 3, 2011
...then build your library
                       on top of that


Tuesday, May 3, 2011
You got yourself a
                       plugin system


Tuesday, May 3, 2011
Build tools to solve the
                       problem


Tuesday, May 3, 2011
❖   Design up front
                       ❖   Make use of conventions
                       ❖   Don’t make me think
                       ❖   Build in hackability

Tuesday, May 3, 2011
Questions?
                       @danwrong

Tuesday, May 3, 2011
@jointheflock
                       twitter.com/jobs
                       dan@twitter.com


Tuesday, May 3, 2011
Eye of the Beholder
Tuesday, May 3, 2011
Chaining
Tuesday, May 3, 2011

More Related Content

What's hot

What's hot (20)

J query lecture 1
J query lecture 1J query lecture 1
J query lecture 1
 
Drupal 8 Hooks
Drupal 8 HooksDrupal 8 Hooks
Drupal 8 Hooks
 
XML Schemas
XML SchemasXML Schemas
XML Schemas
 
Solid in practice
Solid in practiceSolid in practice
Solid in practice
 
Data Binding: Is It the Next Big Thing?
Data Binding: Is It the Next Big Thing?Data Binding: Is It the Next Big Thing?
Data Binding: Is It the Next Big Thing?
 
Dojo Confessions
Dojo ConfessionsDojo Confessions
Dojo Confessions
 
Changeyrmarkup
ChangeyrmarkupChangeyrmarkup
Changeyrmarkup
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
 
J query1
J query1J query1
J query1
 
J query
J queryJ query
J query
 
A to Z about JQuery - Become Newbie to Expert Java Developer
A to Z about JQuery - Become Newbie to Expert Java DeveloperA to Z about JQuery - Become Newbie to Expert Java Developer
A to Z about JQuery - Become Newbie to Expert Java Developer
 
Element
ElementElement
Element
 
Building Persona: federated and privacy-sensitive identity for the Web (Open ...
Building Persona: federated and privacy-sensitive identity for the Web (Open ...Building Persona: federated and privacy-sensitive identity for the Web (Open ...
Building Persona: federated and privacy-sensitive identity for the Web (Open ...
 
jQuery Selectors
jQuery SelectorsjQuery Selectors
jQuery Selectors
 
jQuery Fundamentals
jQuery FundamentalsjQuery Fundamentals
jQuery Fundamentals
 
BVJS
BVJSBVJS
BVJS
 
Electron: From Beginner to Pro
Electron: From Beginner to ProElectron: From Beginner to Pro
Electron: From Beginner to Pro
 
Learn css3
Learn css3Learn css3
Learn css3
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development Toolkit
 
Java Assignment Help
Java  Assignment  HelpJava  Assignment  Help
Java Assignment Help
 

Viewers also liked

生命是何等美麗 -- 我的好朋友
生命是何等美麗 -- 我的好朋友生命是何等美麗 -- 我的好朋友
生命是何等美麗 -- 我的好朋友Mike Chou
 
JavaScript with YUI
JavaScript with YUIJavaScript with YUI
JavaScript with YUIRajat Pandit
 
用50元買來的CEO
用50元買來的CEO用50元買來的CEO
用50元買來的CEOMike Chou
 
Hadoop with Lustre WhitePaper
Hadoop with Lustre WhitePaperHadoop with Lustre WhitePaper
Hadoop with Lustre WhitePaperDavid Luan
 
逆向思考
逆向思考逆向思考
逆向思考Mike Chou
 
Difference Between DOM and SAX parser in java with examples
Difference Between DOM and SAX parser in java with examplesDifference Between DOM and SAX parser in java with examples
Difference Between DOM and SAX parser in java with examplesSaid Benaissa
 
The Mysteries Of JavaScript-Fu (RailsConf Ediition)
The Mysteries Of JavaScript-Fu (RailsConf Ediition)The Mysteries Of JavaScript-Fu (RailsConf Ediition)
The Mysteries Of JavaScript-Fu (RailsConf Ediition)danwrong
 
Big Data and HPC
Big Data and HPCBig Data and HPC
Big Data and HPCNetApp
 
YUI 3: The Most Advance JavaScript Library in the World
YUI 3: The Most Advance JavaScript Library in the WorldYUI 3: The Most Advance JavaScript Library in the World
YUI 3: The Most Advance JavaScript Library in the WorldAra Pehlivanian
 
Seagate NAS: Witness Future of Cloud Computing
Seagate NAS: Witness Future of Cloud ComputingSeagate NAS: Witness Future of Cloud Computing
Seagate NAS: Witness Future of Cloud ComputingThe World Bank
 
Personal Professional Development
Personal Professional DevelopmentPersonal Professional Development
Personal Professional Developmentjschinker
 
JAXB: Create, Validate XML Message and Edit XML Schema
JAXB: Create, Validate XML Message and Edit XML SchemaJAXB: Create, Validate XML Message and Edit XML Schema
JAXB: Create, Validate XML Message and Edit XML SchemaSitdhibong Laokok
 
JavaScript Introduction
JavaScript IntroductionJavaScript Introduction
JavaScript IntroductionJainul Musani
 
Java Script basics and DOM
Java Script basics and DOMJava Script basics and DOM
Java Script basics and DOMSukrit Gupta
 

Viewers also liked (20)

生命是何等美麗 -- 我的好朋友
生命是何等美麗 -- 我的好朋友生命是何等美麗 -- 我的好朋友
生命是何等美麗 -- 我的好朋友
 
JavaScript with YUI
JavaScript with YUIJavaScript with YUI
JavaScript with YUI
 
用50元買來的CEO
用50元買來的CEO用50元買來的CEO
用50元買來的CEO
 
Hadoop with Lustre WhitePaper
Hadoop with Lustre WhitePaperHadoop with Lustre WhitePaper
Hadoop with Lustre WhitePaper
 
逆向思考
逆向思考逆向思考
逆向思考
 
Difference Between DOM and SAX parser in java with examples
Difference Between DOM and SAX parser in java with examplesDifference Between DOM and SAX parser in java with examples
Difference Between DOM and SAX parser in java with examples
 
自在
自在自在
自在
 
The Mysteries Of JavaScript-Fu (RailsConf Ediition)
The Mysteries Of JavaScript-Fu (RailsConf Ediition)The Mysteries Of JavaScript-Fu (RailsConf Ediition)
The Mysteries Of JavaScript-Fu (RailsConf Ediition)
 
Big Data and HPC
Big Data and HPCBig Data and HPC
Big Data and HPC
 
YUI 3: The Most Advance JavaScript Library in the World
YUI 3: The Most Advance JavaScript Library in the WorldYUI 3: The Most Advance JavaScript Library in the World
YUI 3: The Most Advance JavaScript Library in the World
 
Seagate NAS: Witness Future of Cloud Computing
Seagate NAS: Witness Future of Cloud ComputingSeagate NAS: Witness Future of Cloud Computing
Seagate NAS: Witness Future of Cloud Computing
 
Personal Professional Development
Personal Professional DevelopmentPersonal Professional Development
Personal Professional Development
 
JAXB: Create, Validate XML Message and Edit XML Schema
JAXB: Create, Validate XML Message and Edit XML SchemaJAXB: Create, Validate XML Message and Edit XML Schema
JAXB: Create, Validate XML Message and Edit XML Schema
 
Java and XML
Java and XMLJava and XML
Java and XML
 
Understanding XML DOM
Understanding XML DOMUnderstanding XML DOM
Understanding XML DOM
 
JavaScript Introduction
JavaScript IntroductionJavaScript Introduction
JavaScript Introduction
 
Xml processors
Xml processorsXml processors
Xml processors
 
JAXB
JAXBJAXB
JAXB
 
Java Script basics and DOM
Java Script basics and DOMJava Script basics and DOM
Java Script basics and DOM
 
XML SAX PARSING
XML SAX PARSING XML SAX PARSING
XML SAX PARSING
 

Similar to Building Non-shit APIs with JavaScript

What's in a language? By Cheng Lou
What's in a language? By Cheng Lou What's in a language? By Cheng Lou
What's in a language? By Cheng Lou React London 2017
 
Write better python code with these 10 tricks | by yong cui, ph.d. | aug, 202...
Write better python code with these 10 tricks | by yong cui, ph.d. | aug, 202...Write better python code with these 10 tricks | by yong cui, ph.d. | aug, 202...
Write better python code with these 10 tricks | by yong cui, ph.d. | aug, 202...amit kuraria
 
Apache Utilities At Work V5
Apache Utilities At Work   V5Apache Utilities At Work   V5
Apache Utilities At Work V5Tom Marrs
 
All you need to know about JavaScript Functions
All you need to know about JavaScript FunctionsAll you need to know about JavaScript Functions
All you need to know about JavaScript FunctionsOluwaleke Fakorede
 
Ext GWT 3.0 Advanced Templates
Ext GWT 3.0 Advanced TemplatesExt GWT 3.0 Advanced Templates
Ext GWT 3.0 Advanced TemplatesSencha
 
Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)MongoSF
 
The Django Book - Chapter 7 forms
The Django Book - Chapter 7 formsThe Django Book - Chapter 7 forms
The Django Book - Chapter 7 formsVincent Chien
 
Designing an ExtJS user login panel
Designing an ExtJS user login panelDesigning an ExtJS user login panel
Designing an ExtJS user login panelArun Prasad
 
Ext js user login panel
Ext js user login panelExt js user login panel
Ext js user login panelArun Prasad
 
Migrating from Ext GWT 2.x to 3.0
Migrating from Ext GWT 2.x to 3.0Migrating from Ext GWT 2.x to 3.0
Migrating from Ext GWT 2.x to 3.0Sencha
 
Week 4 - jQuery + Ajax
Week 4 - jQuery + AjaxWeek 4 - jQuery + Ajax
Week 4 - jQuery + Ajaxbaygross
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012Yaqi Zhao
 
Roger Kenner Automating Posting
Roger Kenner Automating PostingRoger Kenner Automating Posting
Roger Kenner Automating PostingRoger Kenner
 
Week32
Week32Week32
Week32H K
 
JavaScript: Ajax & DOM Manipulation
JavaScript: Ajax & DOM ManipulationJavaScript: Ajax & DOM Manipulation
JavaScript: Ajax & DOM Manipulationborkweb
 

Similar to Building Non-shit APIs with JavaScript (20)

What's in a language? By Cheng Lou
What's in a language? By Cheng Lou What's in a language? By Cheng Lou
What's in a language? By Cheng Lou
 
Write better python code with these 10 tricks | by yong cui, ph.d. | aug, 202...
Write better python code with these 10 tricks | by yong cui, ph.d. | aug, 202...Write better python code with these 10 tricks | by yong cui, ph.d. | aug, 202...
Write better python code with these 10 tricks | by yong cui, ph.d. | aug, 202...
 
Apache Utilities At Work V5
Apache Utilities At Work   V5Apache Utilities At Work   V5
Apache Utilities At Work V5
 
All you need to know about JavaScript Functions
All you need to know about JavaScript FunctionsAll you need to know about JavaScript Functions
All you need to know about JavaScript Functions
 
Ext GWT 3.0 Advanced Templates
Ext GWT 3.0 Advanced TemplatesExt GWT 3.0 Advanced Templates
Ext GWT 3.0 Advanced Templates
 
Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)
 
The Django Book - Chapter 7 forms
The Django Book - Chapter 7 formsThe Django Book - Chapter 7 forms
The Django Book - Chapter 7 forms
 
Automating Ievb
Automating IevbAutomating Ievb
Automating Ievb
 
Designing an ExtJS user login panel
Designing an ExtJS user login panelDesigning an ExtJS user login panel
Designing an ExtJS user login panel
 
Ext js user login panel
Ext js user login panelExt js user login panel
Ext js user login panel
 
Migrating from Ext GWT 2.x to 3.0
Migrating from Ext GWT 2.x to 3.0Migrating from Ext GWT 2.x to 3.0
Migrating from Ext GWT 2.x to 3.0
 
The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 
Week 4 - jQuery + Ajax
Week 4 - jQuery + AjaxWeek 4 - jQuery + Ajax
Week 4 - jQuery + Ajax
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012
 
68837.ppt
68837.ppt68837.ppt
68837.ppt
 
Roger Kenner Automating Posting
Roger Kenner Automating PostingRoger Kenner Automating Posting
Roger Kenner Automating Posting
 
Week32
Week32Week32
Week32
 
J Query Public
J Query PublicJ Query Public
J Query Public
 
Os Leonard
Os LeonardOs Leonard
Os Leonard
 
JavaScript: Ajax & DOM Manipulation
JavaScript: Ajax & DOM ManipulationJavaScript: Ajax & DOM Manipulation
JavaScript: Ajax & DOM Manipulation
 

More from danwrong

Loadrunner
LoadrunnerLoadrunner
Loadrunnerdanwrong
 
Bringing the Same-Origin Policy to its Knees
Bringing the Same-Origin Policy to its KneesBringing the Same-Origin Policy to its Knees
Bringing the Same-Origin Policy to its Kneesdanwrong
 
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)danwrong
 
8 Minutes On Rack
8 Minutes On Rack8 Minutes On Rack
8 Minutes On Rackdanwrong
 
Taming The Beast
Taming The BeastTaming The Beast
Taming The Beastdanwrong
 
Metaprogramming JavaScript
Metaprogramming  JavaScriptMetaprogramming  JavaScript
Metaprogramming JavaScriptdanwrong
 
The Mysteries Of JavaScript-Fu (@media Europe Edition)
The Mysteries Of JavaScript-Fu (@media Europe Edition)The Mysteries Of JavaScript-Fu (@media Europe Edition)
The Mysteries Of JavaScript-Fu (@media Europe Edition)danwrong
 
The Mysteries Of JavaScript-Fu (@media SF Edition)
The Mysteries Of JavaScript-Fu (@media SF Edition)The Mysteries Of JavaScript-Fu (@media SF Edition)
The Mysteries Of JavaScript-Fu (@media SF Edition)danwrong
 

More from danwrong (8)

Loadrunner
LoadrunnerLoadrunner
Loadrunner
 
Bringing the Same-Origin Policy to its Knees
Bringing the Same-Origin Policy to its KneesBringing the Same-Origin Policy to its Knees
Bringing the Same-Origin Policy to its Knees
 
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)
 
8 Minutes On Rack
8 Minutes On Rack8 Minutes On Rack
8 Minutes On Rack
 
Taming The Beast
Taming The BeastTaming The Beast
Taming The Beast
 
Metaprogramming JavaScript
Metaprogramming  JavaScriptMetaprogramming  JavaScript
Metaprogramming JavaScript
 
The Mysteries Of JavaScript-Fu (@media Europe Edition)
The Mysteries Of JavaScript-Fu (@media Europe Edition)The Mysteries Of JavaScript-Fu (@media Europe Edition)
The Mysteries Of JavaScript-Fu (@media Europe Edition)
 
The Mysteries Of JavaScript-Fu (@media SF Edition)
The Mysteries Of JavaScript-Fu (@media SF Edition)The Mysteries Of JavaScript-Fu (@media SF Edition)
The Mysteries Of JavaScript-Fu (@media SF Edition)
 

Recently uploaded

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 organizationRadu Cotescu
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
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 AutomationSafe Software
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
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 MenDelhi Call girls
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
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.pptxEarley Information Science
 
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...Martijn de Jong
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
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 textsMaria Levchenko
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
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 MenDelhi Call girls
 
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 Scriptwesley chun
 

Recently uploaded (20)

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
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
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
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
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
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
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
 
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...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
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
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
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
 
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
 

Building Non-shit APIs with JavaScript

  • 1. Your JS Library Dan Webb AKA @danwrong Tuesday, May 3, 2011
  • 6. We all know what happened next... jQuery The Rest Tuesday, May 3, 2011
  • 8. Internals were not important... Tuesday, May 3, 2011
  • 9. ...what had John created was a great interface Tuesday, May 3, 2011
  • 10. "All programmers are API designers" Joshua Bloch (http://lcsd05.cs.tamu.edu/slides/keynote.pdf) Tuesday, May 3, 2011
  • 11. The API is priority #1 Tuesday, May 3, 2011
  • 12. ❖ Predictability ❖ Simplicity ❖ Flexibility Tuesday, May 3, 2011
  • 14. Tuesday, May 3, 2011 RTFM
  • 16. Think about your audience... Tuesday, May 3, 2011
  • 17. ...use conventions people already know Tuesday, May 3, 2011
  • 18. Language conventions and standard library Tuesday, May 3, 2011
  • 21. Be careful with polyfills Tuesday, May 3, 2011
  • 23. var paper = Raphael(10, 50, 320, 200); var c = paper.circle(50, 40, 10); c.attr("fill", "#f00"); c.show(); Tuesday, May 3, 2011
  • 25. a.internal { color: #44e534; text-decoration: none; } $('a.external').css({ color: '#44e534', textDecoration: 'none' }); Tuesday, May 3, 2011
  • 26. Example: creating a DOM Builder Tuesday, May 3, 2011
  • 27. node.innerHTML = '<form method="post" action="/action">' + '<p>' + '<label>' + 'Username: <input type="text" name="username">' + '</label>' + '<label>' + 'Password: <input type="password" name="password">' + '</label>' + '</p>' + '</form>'; var form = document.createElement('form'); var p = document.createElement('p'); form.setAttribute('action', '/login'); form.setAttribute('method', 'post'); var usernameLabel = document.createElement('label'); var usernameText = document.createTextElement('Username: '); var usernameInput = document.createElement('input'); usernameInput.setAttribute('type', 'text'); usernameInput.setAttribute('name', 'username'); form.appendChild(p); p.appendChild(usernameLabel); // ... at this point I decided to give // all this up and become a farmer Tuesday, May 3, 2011
  • 28. var html = { element: function(name, attributes, children) { var node = document.createElement(name); for (var attr in attributes) { node.setAttribute(attr, attributes[attr]); } for (var i=0, len=children.length; i < len; i++) { node.appendChild(children[i]); } return node; } } Tuesday, May 3, 2011
  • 29. var form = html.element( 'form', { action: '/login', method: 'post' } [ html.element('p', {}, [ html.element('label', {}, [ document.createTextElement('Username: '), html.element('input', { type: 'text', name: 'username' }, []), // ... you get the idea ]) ]) ] ); Tuesday, May 3, 2011
  • 30. var form = html.form({ action: '/login', method: 'post' }, [ html.p({}, [ html.label({}, [ document.createTextElement('Username: '), html.input({ type: 'text', name: 'username' }, []), // ... you still get the idea, right? ]) ]) ] ); Tuesday, May 3, 2011
  • 31. function elementBuilder(name) { return function(attributes, children) { return html.element(name, attributes, children); } } function generateBuilderFunctions(elements) { for (var i=0, len=elements.length; i < len; i++) { html[elements[i]] = createElementBuilder(elements[i]); } } generateBuilderFunctions("p|div|span|strong|em|img|table|tr| td|th|thead|tbody|tfoot|pre|code|h1|h2|h3|h4|h5|h6|ul|ol|li| form|input|textarea|legend|fieldset|select|option| blockquote|cite|br|hr|dd|dl|dt|address|a|button|abbr| acronym|script|link|style|bdo|ins|del|object|param|col| colgroup|optgroup|caption|label|dfn|kbd|samp|var".split ("|")); Tuesday, May 3, 2011
  • 34. Don’t make me RTFM again... Tuesday, May 3, 2011
  • 38. var evt = document.createEvent("MouseEvents"); evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); Tuesday, May 3, 2011
  • 39. element.addEventListener('input', function() { // do some front-end magic }, false); Tuesday, May 3, 2011
  • 40. var evt = document.createEvent("MouseEvents"); evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); Tuesday, May 3, 2011
  • 41. Use options hashes for optional arguments Tuesday, May 3, 2011
  • 42. evt.initMouseEvent("click", { bubble: false, relatedTarget: thing }); Tuesday, May 3, 2011
  • 43. http://blog.rebeccamurphey.com/objects-as- arguments-in-javascript-where-do-y Tuesday, May 3, 2011
  • 44. Function calls should read well Tuesday, May 3, 2011
  • 45. // replace oldNode with newNode - DOM API oldNode.parentNode.replaceChild(newNode, oldNode); // Dojo dojo.place(newNode, oldNode, "replace"); // jQuery $(oldNode).replaceWith(newNode); Tuesday, May 3, 2011
  • 46. Mask complexity if possible Tuesday, May 3, 2011
  • 47. var con = xd.connect({ src: 'http://danwebb.net/receiver' }); con.bind('ready', function() { rpc(con).call('getData', function(result) { alert(result); }); }); Tuesday, May 3, 2011
  • 48. xd.connect({ src: 'http://danwebb.net/receiver' }, function(con) { rpc(con).call('getData', function(result) { alert(result); }); }); Tuesday, May 3, 2011
  • 49. var con = xd.connect({ src: 'http://danwebb.net/receiver' }); rpc(con).call('getData', function(result) { alert(result); }); Tuesday, May 3, 2011
  • 50. Back to the DOM Builder Tuesday, May 3, 2011
  • 51. var form = html.form({ action: '/login', method: 'post' }, [ html.p({}, [ html.label({}, [ document.createTextElement('Username: '), html.input({ type: 'text', name: 'username' }, []), // ... you still get the idea, right? ]) ]) ] ); Tuesday, May 3, 2011
  • 52. var form = html.form({ method: 'post', action: '/login' }, html.p( html.label( 'Username: ', html.input({ type: 'text', name: 'username' }) ), html.label( 'Password: ', html.input({ type: 'password', name: 'pass' }) ), html.input({ type: 'submit', value: 'Login'}) ) ); Tuesday, May 3, 2011
  • 53. function elementBuilder(name) { return function() { var attributes = {}, children = [], args = Array.prototype.slice.call(arguments); // if the first arg is not a element or a string then its an attributes hash if (!args[0].nodeType && typeof args[0] != 'string') { attributes = args.unshift(); } // children can be an array or remaining args if (Array.isArray(args[0])) { args = args[0]; } // add rest of args as children converting any strings to text nodes for (var i=0, len=args.length; i < len; i++) { if (typeof args[i] == 'string') { children.push(document.createTextNode(args[i])); } else { children.push(args[i]); } } return html.element(name, attributes, children); } } Tuesday, May 3, 2011
  • 58. Remember: you can't please everyone Tuesday, May 3, 2011
  • 59. Don’t try to second guess every use case Tuesday, May 3, 2011
  • 60. Options hashes != flexibility Tuesday, May 3, 2011
  • 64. var lib = (function() { var private = function() { // you can't mess with me }; return { _internal: function() { // you probably shouldn't mess with me }, public: function() { // I'm part of the API - call me sometime } } }()); Tuesday, May 3, 2011
  • 66. // https://github.com/ender-js/Ender $._select = function(selector, root) { return Sizzle(selector, root); } $._select = function (selector, root) { return (root || document).querySelectorAll(selector); }); Tuesday, May 3, 2011
  • 68. // github.com/danwrong/loadrunner function Mustache(path) { this.path = path; } Mustache.prototype = new loadrunner.Dependency; Mustache.prototype.start = function() { var me = this; $.get(this.path, function(result) { var template = Mustache.parse(result); me.complete(template); }); } using(new Mustache('thing.mustache'), function(template) { template.evaluate({ a: 'yep', b: 'nope' }); }); Tuesday, May 3, 2011
  • 70. Meanwhile, back in DOM Builder land... Tuesday, May 3, 2011
  • 71. function elementBuilder(name) { return function() { // code collapsed for clarity // add rest of args as children // converting any strings to text nodes for (var i=0, len=args.length; i < len; i++) { if (typeof args[i] == 'string') { node = document.createTextNode(args[i]); } else { if (typeof args[i].toDOM == 'function') { node = args[i].toDOM(); } else { node = args[i]; } } children.push(node); } return html.element(name, attributes, children); } } Tuesday, May 3, 2011
  • 72. function Tweet(text, author, timestamp) { this.text = text; this.author = author; this.timestamp = timestamp; } Tweet.prototype.toDOM = function() { return html.p( { 'class': 'tweet' }, html.strong(this.author.name), this.text, html.span({ 'class': 'time' }, this.timestamp) ); } var timeline = // an array of Tweet objects document.appendChild(html.div({ id: 'timeline' }, timeline)); Tuesday, May 3, 2011
  • 73. Create a framework for solving your problem... Tuesday, May 3, 2011
  • 74. ...then build your library on top of that Tuesday, May 3, 2011
  • 75. You got yourself a plugin system Tuesday, May 3, 2011
  • 76. Build tools to solve the problem Tuesday, May 3, 2011
  • 77. Design up front ❖ Make use of conventions ❖ Don’t make me think ❖ Build in hackability Tuesday, May 3, 2011
  • 78. Questions? @danwrong Tuesday, May 3, 2011
  • 79. @jointheflock twitter.com/jobs dan@twitter.com Tuesday, May 3, 2011
  • 80. Eye of the Beholder Tuesday, May 3, 2011