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

Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

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