SlideShare a Scribd company logo
JavaScript
HELLO
                     my name is




              @AARONIUS   · AARONHARDY.COM
Software Engineer, Adobe Digital Marketing Suite
   We enable management, measurement, execution, and
     optimization of digital advertising and marketing.
No hidden agenda
Single-Page Apps
TabBar
  CurrencyFormatter

   EventDispatcher        List     ArrayCollection
                 DataGroup
DragManager                           ToggleButtonBar
                  Panel
                                      NumericStepper
    Slider
                ViewStack
                                  Accordion
Bindable
                  DataGrid                Effects
AccountInfo
                                   (Group)
                   Header
                  (Group)
                                    Menu
                              (ToggleButtonBar)


     Main
                                                    Biography
(Application)
                                                     (Group)
                                   Artist
                                  (Group)
                                                  Similar Artists
                                                       (List)
                   Music        Discography
                (ViewStack)     (DataGroup)


                                Discussion
                                (DataGroup)
?                  Links          ?
          Basic Form Elements
Div
          Image      ?               Bulleted Lists

                                         ?
 ?                Span           ?
<html>
    <head>
        <script>
            buckets of vomit
            buckets of vomit
            buckets of vomit
            buckets of vomit
            buckets of vomit
        </script>
    </head>
    <body>
        buckets of vomit
        buckets of vomit
        buckets of vomit
        buckets of vomit
        buckets of vomit
    </body>
</html>
•   IDEs
•   MVC
•   Widgets/Components
•   Dependency management
•   DOM manipulation
•   Templating
•   Testing
•   Utilities
•   JavaScript + HTML + CSS
Quality ide
Libraries
Rolling your own
jquery
    underscore.js
     backbone.js
      requirejs
All MIT license (+ other options) and on GitHub
Learn Javascript
Never build large apps
 The secret to building large apps is NEVER build
 large apps. Break up your applications into small
 pieces. Then, assemble those testable, bite-sized
 pieces into your big application.
 – Justin Meyer
Admit what you
      don’t know
The key is to acknowledge from the start that you
have no idea how this will grow. When you accept
that you don’t know everything, you begin to
design the system defensively.
– Nicholas Zakas
Add "use strict"; before code or at beginning of
function to help decrapify your code.

• Eliminates pitfalls by raising errors
• Improves JS engine optimization
• Prohibits syntax reserved for future JS versions

* Won’t be used in examples to save slide space
JSLint or JSHint.

•   Run in IDE.
•   Run on command line.
•   Run in build scripts.
•   Copy-paste into web interface.
•   Use flags for configuration.
General community style:
• Names of directories and files shall be lowercase and
  hyphens shall be used to separate words.
• Variable names shall be camelCase.
• Classes (functions) to be instantiated shall start with a
  capital letter.
• Members intended to be private shall be prefixed with
  an underscore.
Loose typing == more testing!

•   JsTestDriver
•   QUnit
•   Jasmine
•   Vows
•   …and bucket-loads more
jquery
• Not an application framework!
• Abstracts the DOM
    • Style
    • Position
    • Behavior
    • Animation
    • Creation/Removal
• AJAX requests
• Utilities for objects, arrays, strings, etc.
• “Framework” for UI widgets and utilities
Usage by Top Sites




http://trends.builtwith.com/javascript/jQuery
• Performance-tuned servers
• Allows browser to have more concurrent connections
• Cross-site caching
Toolbox of array, object, and function manipulation
utilities.
var names = _.pluck(
       [{name: 'moe', age: 40}, {name: 'larry', age: 50}],
       'name');
var person = _.extend({name: 'moe'}, {age: 50});
var uniques = _.union([1, 2, 3], [101, 2, 10], [2, 1]);


And bucket-loads more…
Old-school
var tweetTemplate = '' +
       '<div>' +
               '<div style="float: left">' +
                      '<img src="' + avatar + '"/>' +
               '</div>' +
               '<div style="margin-left: 60px">' +
                      '<p>' + username + '</p>' +
                      '<p>' + text + '</p>' +
               '</div>' +
       '<div>';
Old-school
• HTML buried in logic (hard to re-skin)
• Concatenation/escaping takes time and is error-prone
• IDE might not code-hint or color-code properly
• Boring and tedious
New-school
<script type="text/template" id="tweet-template">
       <div>
               <div style="float: left">
                      <img src="<%= avatar %>"/>
               </div>
               <div style="margin-left: 60px">
                      <p><%= username %></p>
                      <p><%= text %></p>
               </div>
       </div>
</script>
<script>
       var tweet = {avatar: 'aaronius.jpg', alias: '@Aaronius',
               text: 'Honey roasted peanuts rock my sox.'};
       var template = _.template($('#tweet-template').html());
       var html = template(tweet);
       var element = $(html);
</script>
•   Mustache.js
•   Handlebars.js
•   Jade
•   Eco
•   …and bucket-loads more.

Underscore.js templating is one of the best (though not as
full-featured) and is a dependency of Backbone.js. You can
use any templating engine.
backbone
Object A passes a function
to object B and tells
object B to call the
function when X
occurs. When X
occurs, object B calls the
function.
backbone.events
Dad:
var baby = new Baby();

var changeDeuceTrap = function() {
       baby.deuces = 0;
       baby.cakeHoleShut = true;
};

baby.on('turdDropped', changeDeuceTrap);


Baby:
this.trigger('turdDropped');
Mix into any object or class
var baby = new Baby();
baby = _.extend(baby, Backbone.Events);
baby.on(…);
baby.trigger(…);
backbone.Model
Plain Old JavaScript Object
var book = {
       title: 'A Tale of Two Cities',
       author: 'Charles Dickens',
       genre: 'historical',
       publisher: 'Chapman & Hall'
};

How can another object know when one of book’s values
changes? It can’t!
Eventful Backbone.Model
var book = new Backbone.Model({
       title: 'A Tale of Two Cities',
       author: 'Charles Dickens',
       genre: 'historical',
       publisher: 'Chapman & Hall'
});

book.on('change:genre', function(model, genre) {
       alert('genre for ' + model.get('title') +
               ' changed to ' + genre);
});

book.set({genre: 'social criticism'});
Extending Backbone.Model
var Book = Backbone.Model.extend({
       …custom model logic…
});

var book = new Book({
       title: 'A Tale of Two Cities',
       author: 'Charles Dickens',
       publisher: 'Chapman & Hall'
});
Persistence
HTTP Method   URL         Action

GET           /books      Retrieve all books

GET           /books/10   Retrieve book with id == 10

POST          /books      Add a book

PUT           /books/10   Update book with id == 10

DELETE        /books/10   Delete book with id == 10
Persistence (save)
var Book = Backbone.Model.extend({
       urlRoot: '/books'
});

var book = new Book({title: 'The Tragedy of the Commons'});
book.save();
Persistence (fetch)
var Book = Backbone.Model.extend({
       urlRoot: '/books'
});

var book = new Book({id: 2});

var fetchSuccess = function() {
       alert(book.get('title'));
};

book.fetch({success: fetchSuccess});
JavaScript for Flex Devs
JavaScript for Flex Devs
MODEL
   layersOpen
 characterOpen
magicWandOpen
    colorOpen
     infoOpen
And more…
• Validation
• Extracting native object
• Determine which attributes have changed
• And bucket-loads more…
backbone.collection
Plain Old JavaScript Array:
var books = [book1, book2, book3, book4];

How can another object know when an item is added or
removed from this array? It can’t!
var goodEarth = new Backbone.Model();

var books = new Backbone.Collection();

books.on('add', function(book, books, options) {
       alert('Book ' + book.get('title') + ' added at index ' +
               options.at + '. ' + 'The collection now contains ' +
               books.length + ' models.');
};

books.on('remove', function(book, books, options) {
       alert('Book ' + book.get('title') + ' removed from index ' +
       options.index);
}

books.add(goodEarth);
books.remove(goodEarth);
Event Pass-through
var books = new Backbone.Collection([taleOfTwoCities, goodEarth]);

books.on('change:title', function(book, title) {
       alert('Book title changed from ' +
               book.previous('title') + ' to ' + title);
});

goodEarth.set({title: 'Good Earth, The'});
Persistence (fetch)
var Books = Backbone.Collection.extend({
       model: Book,
       url: '/books'
});

var books = new Books();
books.fetch();
Underscore mix-ins
var titles = books.pluck('title');

each(), reduce(), find(), filter(), reject(), shuffle(), without()
and bucket-loads more!
And more…
• Sorting
• Resetting
• Retrieving model by id or index
• Custom loading and parsing
• …and bucket-loads more!
Backbone view
JavaScript for Flex Devs
JavaScript for Flex Devs
Stats
        Model


Tweet
Model
        Tweet




        Tweet


                 Tweet
                Collection
        Tweet




        Tweet




        Tweet




        Tweet
var Tweet = Backbone.Model.extend({ …view logic… });
var TweetRow = Backbone.View.extend({ …view logic… });

var tweet = new Tweet({
       avatar: 'aaronius.jpg',
       alias: '@Aaronius',
       text: 'Honey roasted peanuts rock my sox.'
});

var row = new TweetRow({
       model: tweet
});
<script type="text/template" id="tweet-row-template">
       <div style="float: left"><img src="<%= avatar %>"/></div>
       <div style="margin-left: 60px">
               <p><%= username %></p>
               <p><%= text %></p>
       </div>
</script>

var TweetRow = Backbone.View.extend({
       _template: _.template($('#tweet-row-template').html()),

       initialize: function() {
              this.render();
       },

       render: function() {
              this.$el.html(this._template(this.model.toJSON()));
              return this;
       }
});
Backbone router
backbone extensions
requirejs
Must we be restricted to working inside a few monstrous
spaghetti files? NO! Then why are they so prevalent?

• “That’s the way JavaScript has been done in the past.”
• “Loading many JavaScript files requires many HTTP
  requests resulting in longer load times.”
• “Dependency management is hard in JavaScript.”

We can do better!
Old school
// What are the dependencies here!?
// What if a new employee had to re-order for some reason!?

<script   src="script3.js"></script>
<script   src="script1.js"></script>
<script   src="script7.js"></script>
<script   src="script6.js"></script>
<script   src="script4.js"></script>
<script   src="script5.js"></script>
<script   src="script9.js"></script>
<script   src="script8.js"></script>
<script   src="script10.js"></script>
<script   src="script2.js"></script>
script8.js   script4.js   script3.js    script1.js




script2.js                script10.js   script7.js




script9.js   script5.js   script6.js
ServerJS 
      CommonJS 
           Module 
                Async module definition (AMD) 
                      RequireJS
book.js
define({
    title: "My Sister's Keeper",
    publisher: "Atria"
});


bookshelf.js
define([
       'book'
], function(book) {
       return {
               listBook: function() {
                      alert(book.title);
               }
       };
});
index.html
<!DOCTYPE html>
<html>
        <head>
                <title>RequireJS Example</title>
                <script data-main="js/main“
                       src="js/libs/require.js"></script>
        </head>
        <body/>
</html>

main.js
require([
       'bookshelf'
], function(bookshelf) {
       bookshelf.listBook();
});
templates/book.tpl.html
<span class="label">Title:</span>
<span class="value"><%= title %></span><br/>

<span class="label">Author:</span>
<span class="value"><%= author %></span><br/>

<span class="label">Genre:</span>
<span class="value"><%= genre %></span>
book-view.js
define([
       'backbone', 'underscore', 'text!templates/book.tpl.html'
], function(Backbone, _, template) {
       return Backbone.View.extend({
               _template: _.template(template),

              initialize: function() {
                     this.render();
              },

              render: function() {
                     var nativeBook = this.model.toJSON();
                     var html = this._template(nativeBook);
                     this.$el.html(html);
                     return this;
              }
       });
});
bookshelf-view.js
define([
       'backbone',
       'underscore',
       'book-view'
], function(Backbone, _, BookView) {
       return Backbone.View.extend({
               … create child book views as necessary …
               … new BookView() …
       });
});
requirejs optimization
Thank you!

  @Aaronius
aaronhardy.com
encore
(stuff I fit in if time allows)
Persistence with custom url pattern:
var Book = Backbone.Model.extend({
       urlRoot: '/books',
       url: function() {
               return this.urlRoot + '?id=' + this.get('id');
       }
})

var book = new Book({id: 2});
book.fetch();
var App = Backbone.View.extend({
       initialize: function() {
               this.render();
       },

       render: function() {
              var tweet = new Tweet({
                      avatar: 'avatar.jpg',
                      username: '@Aaronius',
                      text: 'Honey roasted peanuts rock my sox.'
              });

              var row = new TweetRow({
                     model: tweet
              });

              this.$el.append(row.$el);
              return this;
       }
});
var app = new App({el: $('body')});
var DocumentView = Backbone.View.extend({
       events: {
               "dblclick"                : "open",
               "click .icon.doc"         : "select",
               "mouseover .title .date" : "showTooltip"
       },

       render: function() { ... },
       open: function() { ... },
       select: function() { ... },
       showTooltip: function() { ... },
});
<script type="text/javascript">
       $(function() {
               var AppRouter = Backbone.Router.extend({
                      routes: {
                              "shirt/id/:id": "showShirt"
                      },

                      showShirt: function(id) {
                             alert('Show shirt with id ' + id);
                      }
              });

              var appRouter = new AppRouter();
              Backbone.history.start();
       });
</script>

<a href="#shirt/id/5">Shirt with id of 5</a><br>
<a href="#shirt/id/10">Shirt with id of 10</a><br>
<a href="#shirt/id/15">Shirt with id of 15</a><br>
<script type="text/javascript">
$(function() {
       var AppRouter = Backbone.Router.extend({
               routes: {
                      ":product/:attribute/:value": "showProduct"
               },

              showProduct: function(product, attribute, value) {
                     alert('Show ' + product + ' where ' +
                             attribute + ' = ' + value + '.');
              }
       });

       var appRouter = new AppRouter();
       Backbone.history.start();
});
</script>

<a href="#shoe/size/12">Size 12 shoes</a><br>
<a href="#shirt/id/5">Shirt with id of 5</a><br>
<a href="#hat/color/black">Black hats</a>
var AppRouter = Backbone.Router.extend({
       routes: {
               ":product/:attribute/:value": "showProduct"
       }
});

var MyView = Backbone.View.extend({
       initialize: function(options) {
               options.router.on('route:showProduct',
                      this._showProduct);
       }

       _showProduct: function(product, attribute, value) {
              alert('Update to show ' + product + ' where '
                      + attribute + ' = ' + value + '.');
       }
});

var appRouter = new AppRouter();
var view = new MyView({router: appRouter});
Backbone.history.start();
Fragment Identifier
• Using URLs in unintended ways
• Dependent on JavaScript
• Controversial
• Used by many popular sites
pushState aka HTML5 History
• The bee’s knees
• Allows changing of core url without changing pages
• Long-term solution
• Browser support lacking (guess which browser)
Ad

Recommended

Dependency Management with RequireJS
Dependency Management with RequireJS
Aaronius
 
Drupal & javascript
Drupal & javascript
Almog Baku
 
Drupal Development (Part 2)
Drupal Development (Part 2)
Jeff Eaton
 
Drupal Step-by-Step: How We Built Our Training Site, Part 1
Drupal Step-by-Step: How We Built Our Training Site, Part 1
Acquia
 
JavaScript and jQuery Basics
JavaScript and jQuery Basics
Kaloyan Kosev
 
Virtual Madness @ Etsy
Virtual Madness @ Etsy
Nishan Subedi
 
jQuery from the very beginning
jQuery from the very beginning
Anis Ahmad
 
Javascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & Tricks
Hjörtur Hilmarsson
 
Sane Async Patterns
Sane Async Patterns
TrevorBurnham
 
A Short Introduction To jQuery
A Short Introduction To jQuery
Sudar Muthu
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish
 
JavaScript in Drupal 7: What developers need to know
JavaScript in Drupal 7: What developers need to know
katbailey
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
EPAM Systems
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
Jarod Ferguson
 
Client-side MVC with Backbone.js
Client-side MVC with Backbone.js
iloveigloo
 
jQuery: Nuts, Bolts and Bling
jQuery: Nuts, Bolts and Bling
Doug Neiner
 
Viking academy backbone.js
Viking academy backbone.js
Bert Wijnants
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
Rebecca Murphey
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutes
Simon Willison
 
Write Less Do More
Write Less Do More
Remy Sharp
 
Drupal Development
Drupal Development
Jeff Eaton
 
A New Baseline for Front-End Devs
A New Baseline for Front-End Devs
Rebecca Murphey
 
JQuery introduction
JQuery introduction
NexThoughts Technologies
 
jQuery Loves Developers - Oredev 2009
jQuery Loves Developers - Oredev 2009
Remy Sharp
 
Yearning jQuery
Yearning jQuery
Remy Sharp
 
jQuery
jQuery
Vishwa Mohan
 
Managing State in Single Page WebApps with Ember.js
Managing State in Single Page WebApps with Ember.js
Mark Mansour
 
Dr. Strangelove or: How I learned to stop worrying and love HTML, CSS and Jav...
Dr. Strangelove or: How I learned to stop worrying and love HTML, CSS and Jav...
RobotDeathSquad
 
Client-side MVC with Backbone.js (reloaded)
Client-side MVC with Backbone.js (reloaded)
iloveigloo
 
JavaScript!
JavaScript!
RTigger
 

More Related Content

What's hot (20)

Sane Async Patterns
Sane Async Patterns
TrevorBurnham
 
A Short Introduction To jQuery
A Short Introduction To jQuery
Sudar Muthu
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish
 
JavaScript in Drupal 7: What developers need to know
JavaScript in Drupal 7: What developers need to know
katbailey
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
EPAM Systems
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
Jarod Ferguson
 
Client-side MVC with Backbone.js
Client-side MVC with Backbone.js
iloveigloo
 
jQuery: Nuts, Bolts and Bling
jQuery: Nuts, Bolts and Bling
Doug Neiner
 
Viking academy backbone.js
Viking academy backbone.js
Bert Wijnants
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
Rebecca Murphey
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutes
Simon Willison
 
Write Less Do More
Write Less Do More
Remy Sharp
 
Drupal Development
Drupal Development
Jeff Eaton
 
A New Baseline for Front-End Devs
A New Baseline for Front-End Devs
Rebecca Murphey
 
JQuery introduction
JQuery introduction
NexThoughts Technologies
 
jQuery Loves Developers - Oredev 2009
jQuery Loves Developers - Oredev 2009
Remy Sharp
 
Yearning jQuery
Yearning jQuery
Remy Sharp
 
jQuery
jQuery
Vishwa Mohan
 
Managing State in Single Page WebApps with Ember.js
Managing State in Single Page WebApps with Ember.js
Mark Mansour
 
Dr. Strangelove or: How I learned to stop worrying and love HTML, CSS and Jav...
Dr. Strangelove or: How I learned to stop worrying and love HTML, CSS and Jav...
RobotDeathSquad
 
A Short Introduction To jQuery
A Short Introduction To jQuery
Sudar Muthu
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish
 
JavaScript in Drupal 7: What developers need to know
JavaScript in Drupal 7: What developers need to know
katbailey
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
EPAM Systems
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
Jarod Ferguson
 
Client-side MVC with Backbone.js
Client-side MVC with Backbone.js
iloveigloo
 
jQuery: Nuts, Bolts and Bling
jQuery: Nuts, Bolts and Bling
Doug Neiner
 
Viking academy backbone.js
Viking academy backbone.js
Bert Wijnants
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
Rebecca Murphey
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutes
Simon Willison
 
Write Less Do More
Write Less Do More
Remy Sharp
 
Drupal Development
Drupal Development
Jeff Eaton
 
A New Baseline for Front-End Devs
A New Baseline for Front-End Devs
Rebecca Murphey
 
jQuery Loves Developers - Oredev 2009
jQuery Loves Developers - Oredev 2009
Remy Sharp
 
Yearning jQuery
Yearning jQuery
Remy Sharp
 
Managing State in Single Page WebApps with Ember.js
Managing State in Single Page WebApps with Ember.js
Mark Mansour
 
Dr. Strangelove or: How I learned to stop worrying and love HTML, CSS and Jav...
Dr. Strangelove or: How I learned to stop worrying and love HTML, CSS and Jav...
RobotDeathSquad
 

Similar to JavaScript for Flex Devs (20)

Client-side MVC with Backbone.js (reloaded)
Client-side MVC with Backbone.js (reloaded)
iloveigloo
 
JavaScript!
JavaScript!
RTigger
 
Planbox Backbone MVC
Planbox Backbone MVC
Acquisio
 
Tikal's Backbone_js introduction workshop
Tikal's Backbone_js introduction workshop
Tikal Knowledge
 
Backbone 4.0
Backbone 4.0
Balavignesh Kasinathan
 
Jquery fundamentals
Jquery fundamentals
Salvatore Fazio
 
User Interface Development with jQuery
User Interface Development with jQuery
colinbdclark
 
Backbonetutorials
Backbonetutorials
shekhar_who
 
A piece of sugar in your client-side development
A piece of sugar in your client-side development
Nicolas Blanco
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
fuser interface-development-using-jquery
fuser interface-development-using-jquery
Kostas Mavridis
 
There's more than web
There's more than web
Matt Evans
 
Front-End Frameworks: a quick overview
Front-End Frameworks: a quick overview
Diacode
 
Advanced JavaScript
Advanced JavaScript
Mahmoud Tolba
 
Javascript frameworks: Backbone.js
Javascript frameworks: Backbone.js
Soós Gábor
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
Ignacio Martín
 
Cleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQuery
Rebecca Murphey
 
The Dom Scripting Toolkit J Query
The Dom Scripting Toolkit J Query
QConLondon2008
 
Prairie Dev Con West - 2012-03-14 - Webmatrix, see what the matrix can do fo...
Prairie Dev Con West - 2012-03-14 - Webmatrix, see what the matrix can do fo...
Frédéric Harper
 
jQuery Plugin
jQuery Plugin
Leo Nguyen
 
Client-side MVC with Backbone.js (reloaded)
Client-side MVC with Backbone.js (reloaded)
iloveigloo
 
JavaScript!
JavaScript!
RTigger
 
Planbox Backbone MVC
Planbox Backbone MVC
Acquisio
 
Tikal's Backbone_js introduction workshop
Tikal's Backbone_js introduction workshop
Tikal Knowledge
 
User Interface Development with jQuery
User Interface Development with jQuery
colinbdclark
 
Backbonetutorials
Backbonetutorials
shekhar_who
 
A piece of sugar in your client-side development
A piece of sugar in your client-side development
Nicolas Blanco
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
fuser interface-development-using-jquery
fuser interface-development-using-jquery
Kostas Mavridis
 
There's more than web
There's more than web
Matt Evans
 
Front-End Frameworks: a quick overview
Front-End Frameworks: a quick overview
Diacode
 
Javascript frameworks: Backbone.js
Javascript frameworks: Backbone.js
Soós Gábor
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
Ignacio Martín
 
Cleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQuery
Rebecca Murphey
 
The Dom Scripting Toolkit J Query
The Dom Scripting Toolkit J Query
QConLondon2008
 
Prairie Dev Con West - 2012-03-14 - Webmatrix, see what the matrix can do fo...
Prairie Dev Con West - 2012-03-14 - Webmatrix, see what the matrix can do fo...
Frédéric Harper
 
Ad

Recently uploaded (20)

FIDO Seminar: Targeting Trust: The Future of Identity in the Workforce.pptx
FIDO Seminar: Targeting Trust: The Future of Identity in the Workforce.pptx
FIDO Alliance
 
Can We Use Rust to Develop Extensions for PostgreSQL? (POSETTE: An Event for ...
Can We Use Rust to Develop Extensions for PostgreSQL? (POSETTE: An Event for ...
NTT DATA Technology & Innovation
 
Murdledescargadarkweb.pdfvolumen1 100 elementary
Murdledescargadarkweb.pdfvolumen1 100 elementary
JorgeSemperteguiMont
 
MuleSoft for AgentForce : Topic Center and API Catalog
MuleSoft for AgentForce : Topic Center and API Catalog
shyamraj55
 
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
SOFTTECHHUB
 
Kubernetes Security Act Now Before It’s Too Late
Kubernetes Security Act Now Before It’s Too Late
Michael Furman
 
Bridging the divide: A conversation on tariffs today in the book industry - T...
Bridging the divide: A conversation on tariffs today in the book industry - T...
BookNet Canada
 
Edge-banding-machines-edgeteq-s-200-en-.pdf
Edge-banding-machines-edgeteq-s-200-en-.pdf
AmirStern2
 
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Alliance
 
Enabling BIM / GIS integrations with Other Systems with FME
Enabling BIM / GIS integrations with Other Systems with FME
Safe Software
 
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance
 
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
AmirStern2
 
Viral>Wondershare Filmora 14.5.18.12900 Crack Free Download
Viral>Wondershare Filmora 14.5.18.12900 Crack Free Download
Puppy jhon
 
“From Enterprise to Makers: Driving Vision AI Innovation at the Extreme Edge,...
“From Enterprise to Makers: Driving Vision AI Innovation at the Extreme Edge,...
Edge AI and Vision Alliance
 
Providing an OGC API Processes REST Interface for FME Flow
Providing an OGC API Processes REST Interface for FME Flow
Safe Software
 
Down the Rabbit Hole – Solving 5 Training Roadblocks
Down the Rabbit Hole – Solving 5 Training Roadblocks
Rustici Software
 
FME for Good: Integrating Multiple Data Sources with APIs to Support Local Ch...
FME for Good: Integrating Multiple Data Sources with APIs to Support Local Ch...
Safe Software
 
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
Safe Software
 
OWASP Barcelona 2025 Threat Model Library
OWASP Barcelona 2025 Threat Model Library
PetraVukmirovic
 
The State of Web3 Industry- Industry Report
The State of Web3 Industry- Industry Report
Liveplex
 
FIDO Seminar: Targeting Trust: The Future of Identity in the Workforce.pptx
FIDO Seminar: Targeting Trust: The Future of Identity in the Workforce.pptx
FIDO Alliance
 
Can We Use Rust to Develop Extensions for PostgreSQL? (POSETTE: An Event for ...
Can We Use Rust to Develop Extensions for PostgreSQL? (POSETTE: An Event for ...
NTT DATA Technology & Innovation
 
Murdledescargadarkweb.pdfvolumen1 100 elementary
Murdledescargadarkweb.pdfvolumen1 100 elementary
JorgeSemperteguiMont
 
MuleSoft for AgentForce : Topic Center and API Catalog
MuleSoft for AgentForce : Topic Center and API Catalog
shyamraj55
 
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
SOFTTECHHUB
 
Kubernetes Security Act Now Before It’s Too Late
Kubernetes Security Act Now Before It’s Too Late
Michael Furman
 
Bridging the divide: A conversation on tariffs today in the book industry - T...
Bridging the divide: A conversation on tariffs today in the book industry - T...
BookNet Canada
 
Edge-banding-machines-edgeteq-s-200-en-.pdf
Edge-banding-machines-edgeteq-s-200-en-.pdf
AmirStern2
 
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Alliance
 
Enabling BIM / GIS integrations with Other Systems with FME
Enabling BIM / GIS integrations with Other Systems with FME
Safe Software
 
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance
 
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
AmirStern2
 
Viral>Wondershare Filmora 14.5.18.12900 Crack Free Download
Viral>Wondershare Filmora 14.5.18.12900 Crack Free Download
Puppy jhon
 
“From Enterprise to Makers: Driving Vision AI Innovation at the Extreme Edge,...
“From Enterprise to Makers: Driving Vision AI Innovation at the Extreme Edge,...
Edge AI and Vision Alliance
 
Providing an OGC API Processes REST Interface for FME Flow
Providing an OGC API Processes REST Interface for FME Flow
Safe Software
 
Down the Rabbit Hole – Solving 5 Training Roadblocks
Down the Rabbit Hole – Solving 5 Training Roadblocks
Rustici Software
 
FME for Good: Integrating Multiple Data Sources with APIs to Support Local Ch...
FME for Good: Integrating Multiple Data Sources with APIs to Support Local Ch...
Safe Software
 
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
Safe Software
 
OWASP Barcelona 2025 Threat Model Library
OWASP Barcelona 2025 Threat Model Library
PetraVukmirovic
 
The State of Web3 Industry- Industry Report
The State of Web3 Industry- Industry Report
Liveplex
 
Ad

JavaScript for Flex Devs

  • 2. HELLO my name is @AARONIUS · AARONHARDY.COM Software Engineer, Adobe Digital Marketing Suite We enable management, measurement, execution, and optimization of digital advertising and marketing.
  • 5. TabBar CurrencyFormatter EventDispatcher List ArrayCollection DataGroup DragManager ToggleButtonBar Panel NumericStepper Slider ViewStack Accordion Bindable DataGrid Effects
  • 6. AccountInfo (Group) Header (Group) Menu (ToggleButtonBar) Main Biography (Application) (Group) Artist (Group) Similar Artists (List) Music Discography (ViewStack) (DataGroup) Discussion (DataGroup)
  • 7. ? Links ? Basic Form Elements Div Image ? Bulleted Lists ? ? Span ?
  • 8. <html> <head> <script> buckets of vomit buckets of vomit buckets of vomit buckets of vomit buckets of vomit </script> </head> <body> buckets of vomit buckets of vomit buckets of vomit buckets of vomit buckets of vomit </body> </html>
  • 9. IDEs • MVC • Widgets/Components • Dependency management • DOM manipulation • Templating • Testing • Utilities • JavaScript + HTML + CSS
  • 13. jquery underscore.js backbone.js requirejs All MIT license (+ other options) and on GitHub
  • 15. Never build large apps The secret to building large apps is NEVER build large apps. Break up your applications into small pieces. Then, assemble those testable, bite-sized pieces into your big application. – Justin Meyer
  • 16. Admit what you don’t know The key is to acknowledge from the start that you have no idea how this will grow. When you accept that you don’t know everything, you begin to design the system defensively. – Nicholas Zakas
  • 17. Add "use strict"; before code or at beginning of function to help decrapify your code. • Eliminates pitfalls by raising errors • Improves JS engine optimization • Prohibits syntax reserved for future JS versions * Won’t be used in examples to save slide space
  • 18. JSLint or JSHint. • Run in IDE. • Run on command line. • Run in build scripts. • Copy-paste into web interface. • Use flags for configuration.
  • 19. General community style: • Names of directories and files shall be lowercase and hyphens shall be used to separate words. • Variable names shall be camelCase. • Classes (functions) to be instantiated shall start with a capital letter. • Members intended to be private shall be prefixed with an underscore.
  • 20. Loose typing == more testing! • JsTestDriver • QUnit • Jasmine • Vows • …and bucket-loads more
  • 22. • Not an application framework! • Abstracts the DOM • Style • Position • Behavior • Animation • Creation/Removal • AJAX requests • Utilities for objects, arrays, strings, etc. • “Framework” for UI widgets and utilities
  • 23. Usage by Top Sites http://trends.builtwith.com/javascript/jQuery
  • 24. • Performance-tuned servers • Allows browser to have more concurrent connections • Cross-site caching
  • 25. Toolbox of array, object, and function manipulation utilities. var names = _.pluck( [{name: 'moe', age: 40}, {name: 'larry', age: 50}], 'name'); var person = _.extend({name: 'moe'}, {age: 50}); var uniques = _.union([1, 2, 3], [101, 2, 10], [2, 1]); And bucket-loads more…
  • 26. Old-school var tweetTemplate = '' + '<div>' + '<div style="float: left">' + '<img src="' + avatar + '"/>' + '</div>' + '<div style="margin-left: 60px">' + '<p>' + username + '</p>' + '<p>' + text + '</p>' + '</div>' + '<div>';
  • 27. Old-school • HTML buried in logic (hard to re-skin) • Concatenation/escaping takes time and is error-prone • IDE might not code-hint or color-code properly • Boring and tedious
  • 28. New-school <script type="text/template" id="tweet-template"> <div> <div style="float: left"> <img src="<%= avatar %>"/> </div> <div style="margin-left: 60px"> <p><%= username %></p> <p><%= text %></p> </div> </div> </script> <script> var tweet = {avatar: 'aaronius.jpg', alias: '@Aaronius', text: 'Honey roasted peanuts rock my sox.'}; var template = _.template($('#tweet-template').html()); var html = template(tweet); var element = $(html); </script>
  • 29. Mustache.js • Handlebars.js • Jade • Eco • …and bucket-loads more. Underscore.js templating is one of the best (though not as full-featured) and is a dependency of Backbone.js. You can use any templating engine.
  • 31. Object A passes a function to object B and tells object B to call the function when X occurs. When X occurs, object B calls the function.
  • 33. Dad: var baby = new Baby(); var changeDeuceTrap = function() { baby.deuces = 0; baby.cakeHoleShut = true; }; baby.on('turdDropped', changeDeuceTrap); Baby: this.trigger('turdDropped');
  • 34. Mix into any object or class var baby = new Baby(); baby = _.extend(baby, Backbone.Events); baby.on(…); baby.trigger(…);
  • 36. Plain Old JavaScript Object var book = { title: 'A Tale of Two Cities', author: 'Charles Dickens', genre: 'historical', publisher: 'Chapman & Hall' }; How can another object know when one of book’s values changes? It can’t!
  • 37. Eventful Backbone.Model var book = new Backbone.Model({ title: 'A Tale of Two Cities', author: 'Charles Dickens', genre: 'historical', publisher: 'Chapman & Hall' }); book.on('change:genre', function(model, genre) { alert('genre for ' + model.get('title') + ' changed to ' + genre); }); book.set({genre: 'social criticism'});
  • 38. Extending Backbone.Model var Book = Backbone.Model.extend({ …custom model logic… }); var book = new Book({ title: 'A Tale of Two Cities', author: 'Charles Dickens', publisher: 'Chapman & Hall' });
  • 39. Persistence HTTP Method URL Action GET /books Retrieve all books GET /books/10 Retrieve book with id == 10 POST /books Add a book PUT /books/10 Update book with id == 10 DELETE /books/10 Delete book with id == 10
  • 40. Persistence (save) var Book = Backbone.Model.extend({ urlRoot: '/books' }); var book = new Book({title: 'The Tragedy of the Commons'}); book.save();
  • 41. Persistence (fetch) var Book = Backbone.Model.extend({ urlRoot: '/books' }); var book = new Book({id: 2}); var fetchSuccess = function() { alert(book.get('title')); }; book.fetch({success: fetchSuccess});
  • 44. MODEL layersOpen characterOpen magicWandOpen colorOpen infoOpen
  • 45. And more… • Validation • Extracting native object • Determine which attributes have changed • And bucket-loads more…
  • 47. Plain Old JavaScript Array: var books = [book1, book2, book3, book4]; How can another object know when an item is added or removed from this array? It can’t!
  • 48. var goodEarth = new Backbone.Model(); var books = new Backbone.Collection(); books.on('add', function(book, books, options) { alert('Book ' + book.get('title') + ' added at index ' + options.at + '. ' + 'The collection now contains ' + books.length + ' models.'); }; books.on('remove', function(book, books, options) { alert('Book ' + book.get('title') + ' removed from index ' + options.index); } books.add(goodEarth); books.remove(goodEarth);
  • 49. Event Pass-through var books = new Backbone.Collection([taleOfTwoCities, goodEarth]); books.on('change:title', function(book, title) { alert('Book title changed from ' + book.previous('title') + ' to ' + title); }); goodEarth.set({title: 'Good Earth, The'});
  • 50. Persistence (fetch) var Books = Backbone.Collection.extend({ model: Book, url: '/books' }); var books = new Books(); books.fetch();
  • 51. Underscore mix-ins var titles = books.pluck('title'); each(), reduce(), find(), filter(), reject(), shuffle(), without() and bucket-loads more!
  • 52. And more… • Sorting • Resetting • Retrieving model by id or index • Custom loading and parsing • …and bucket-loads more!
  • 56. Stats Model Tweet Model Tweet Tweet Tweet Collection Tweet Tweet Tweet Tweet
  • 57. var Tweet = Backbone.Model.extend({ …view logic… }); var TweetRow = Backbone.View.extend({ …view logic… }); var tweet = new Tweet({ avatar: 'aaronius.jpg', alias: '@Aaronius', text: 'Honey roasted peanuts rock my sox.' }); var row = new TweetRow({ model: tweet });
  • 58. <script type="text/template" id="tweet-row-template"> <div style="float: left"><img src="<%= avatar %>"/></div> <div style="margin-left: 60px"> <p><%= username %></p> <p><%= text %></p> </div> </script> var TweetRow = Backbone.View.extend({ _template: _.template($('#tweet-row-template').html()), initialize: function() { this.render(); }, render: function() { this.$el.html(this._template(this.model.toJSON())); return this; } });
  • 62. Must we be restricted to working inside a few monstrous spaghetti files? NO! Then why are they so prevalent? • “That’s the way JavaScript has been done in the past.” • “Loading many JavaScript files requires many HTTP requests resulting in longer load times.” • “Dependency management is hard in JavaScript.” We can do better!
  • 63. Old school // What are the dependencies here!? // What if a new employee had to re-order for some reason!? <script src="script3.js"></script> <script src="script1.js"></script> <script src="script7.js"></script> <script src="script6.js"></script> <script src="script4.js"></script> <script src="script5.js"></script> <script src="script9.js"></script> <script src="script8.js"></script> <script src="script10.js"></script> <script src="script2.js"></script>
  • 64. script8.js script4.js script3.js script1.js script2.js script10.js script7.js script9.js script5.js script6.js
  • 65. ServerJS  CommonJS  Module  Async module definition (AMD)  RequireJS
  • 66. book.js define({ title: "My Sister's Keeper", publisher: "Atria" }); bookshelf.js define([ 'book' ], function(book) { return { listBook: function() { alert(book.title); } }; });
  • 67. index.html <!DOCTYPE html> <html> <head> <title>RequireJS Example</title> <script data-main="js/main“ src="js/libs/require.js"></script> </head> <body/> </html> main.js require([ 'bookshelf' ], function(bookshelf) { bookshelf.listBook(); });
  • 68. templates/book.tpl.html <span class="label">Title:</span> <span class="value"><%= title %></span><br/> <span class="label">Author:</span> <span class="value"><%= author %></span><br/> <span class="label">Genre:</span> <span class="value"><%= genre %></span>
  • 69. book-view.js define([ 'backbone', 'underscore', 'text!templates/book.tpl.html' ], function(Backbone, _, template) { return Backbone.View.extend({ _template: _.template(template), initialize: function() { this.render(); }, render: function() { var nativeBook = this.model.toJSON(); var html = this._template(nativeBook); this.$el.html(html); return this; } }); });
  • 70. bookshelf-view.js define([ 'backbone', 'underscore', 'book-view' ], function(Backbone, _, BookView) { return Backbone.View.extend({ … create child book views as necessary … … new BookView() … }); });
  • 72. Thank you! @Aaronius aaronhardy.com
  • 73. encore (stuff I fit in if time allows)
  • 74. Persistence with custom url pattern: var Book = Backbone.Model.extend({ urlRoot: '/books', url: function() { return this.urlRoot + '?id=' + this.get('id'); } }) var book = new Book({id: 2}); book.fetch();
  • 75. var App = Backbone.View.extend({ initialize: function() { this.render(); }, render: function() { var tweet = new Tweet({ avatar: 'avatar.jpg', username: '@Aaronius', text: 'Honey roasted peanuts rock my sox.' }); var row = new TweetRow({ model: tweet }); this.$el.append(row.$el); return this; } }); var app = new App({el: $('body')});
  • 76. var DocumentView = Backbone.View.extend({ events: { "dblclick" : "open", "click .icon.doc" : "select", "mouseover .title .date" : "showTooltip" }, render: function() { ... }, open: function() { ... }, select: function() { ... }, showTooltip: function() { ... }, });
  • 77. <script type="text/javascript"> $(function() { var AppRouter = Backbone.Router.extend({ routes: { "shirt/id/:id": "showShirt" }, showShirt: function(id) { alert('Show shirt with id ' + id); } }); var appRouter = new AppRouter(); Backbone.history.start(); }); </script> <a href="#shirt/id/5">Shirt with id of 5</a><br> <a href="#shirt/id/10">Shirt with id of 10</a><br> <a href="#shirt/id/15">Shirt with id of 15</a><br>
  • 78. <script type="text/javascript"> $(function() { var AppRouter = Backbone.Router.extend({ routes: { ":product/:attribute/:value": "showProduct" }, showProduct: function(product, attribute, value) { alert('Show ' + product + ' where ' + attribute + ' = ' + value + '.'); } }); var appRouter = new AppRouter(); Backbone.history.start(); }); </script> <a href="#shoe/size/12">Size 12 shoes</a><br> <a href="#shirt/id/5">Shirt with id of 5</a><br> <a href="#hat/color/black">Black hats</a>
  • 79. var AppRouter = Backbone.Router.extend({ routes: { ":product/:attribute/:value": "showProduct" } }); var MyView = Backbone.View.extend({ initialize: function(options) { options.router.on('route:showProduct', this._showProduct); } _showProduct: function(product, attribute, value) { alert('Update to show ' + product + ' where ' + attribute + ' = ' + value + '.'); } }); var appRouter = new AppRouter(); var view = new MyView({router: appRouter}); Backbone.history.start();
  • 80. Fragment Identifier • Using URLs in unintended ways • Dependent on JavaScript • Controversial • Used by many popular sites pushState aka HTML5 History • The bee’s knees • Allows changing of core url without changing pages • Long-term solution • Browser support lacking (guess which browser)

Editor's Notes

  • #12: Is the product part of a larger suite? What is the rest of the suite using?How hard would it be for us to refactor to another library?Is it a fad or popular for good reason?What’s the community like?How open-source is it?What’s the learning curve?How easy is it to hire developers that want to work with it?
  • #29: How to handle many templates.
  • #31: MV* Application FrameworkNon-prescriptive1200 lines of code (with comments)Extensible
  • #33: Like EventDispatcher
  • #36: Like [Bindable] model
  • #47: Like ArrayCollection
  • #50: Similar to PropertyChangeEvent
  • #56: Case Study: Update view when tweet is sent
  • #57: Case Study: Update view when tweet is sent
  • #59: Significance of this.el
  • #66: Kevin Dangoor