SlideShare a Scribd company logo
1 of 49
Download to read offline
JavaScript
Interfaces
in HTML5

Aaron Gustafson
Easy Designs, LLC
slideshare.net/AaronGustafson
JavaScript Interfaces




Working with media
JavaScript Interfaces




Working with media
<audio controls="controls" autobuffer="autobuffer"
        preload="auto">
 <source src="my.mp3"/>
 <source src="my.oga"/>
 <ul>
   <li><a href="my.mp3">Download as audio/mp3</a></li>
   <li><a href="my.oga">Download as audio/ogg</a></li>
 </ul>
</audio>
JavaScript Interfaces




Roll your own player
$('audio').each(function(){
   var audio = this,
   $button = $('<button>Play</button>')
               .click(function(){
                  audio.play();
                });
   $(this)
    .removeAttr('controls')
    .after($button);
 });
                                                 Using jQuery
JavaScript Interfaces




Roll your own
currentSrc
Returns the address of the current media resource (or empty).
networkState
Returns a number (0-3) to indicate the network activity of the element:
  0 = not initialized
  1 = initialized, but idle
  2 = actively downloading
  3 = no resource
buffered
Returns a TimeRange for what’s been buffered by the browser.
duration
Returns the length (in seconds) of the media object, NaN when resource isn’t found.
currentTime
Current playback position (in seconds). Can be set to seek a time.
initialTime
Returns the initial (possibly sought) playback position when the resource was loaded.
JavaScript Interfaces




Roll your own
readyState
A numeric value (0-4) representing the current state of the element:
  0 = no information available
  1 = metadata received
  2 = have current data, but not enough to do anything yet
  3 = have a little future data, but not a lot
  4 = have enough data to advance without risking a stop (at the default playback rate).
paused
Returns true or false based on the state of the media.
ended
Returns true if playback has reached the end of the media resource.
playbackRate
Returns the current playback rate (usually 1.0), but is also settable.
defaultPlaybackRate
Returns the default playback rate (usually 1.0), but is also settable.
JavaScript Interfaces




Roll your own
played
Returns a TimeRange object that tells how much of the media resource has been played.
load()
Triggers the reset and restart of a media resource.
play()
Plays the audio.
pause()
Pauses the audio.
canPlayType( type )
Returns “probably,” “maybe” or empty (for no) based on how confident the browser is.
seeking
Returns true if the user agent is currently seeking.
seekable
Returns a TimeRange object that represents the “seekable” area of the media resource.
JavaScript Interfaces




Test for native support
var
audio     = document.createElement('audio'),
test      = { mp3: 'audio/mpeg',
              oga: 'audio/ogg; codecs="vorbis"' },
supported = [];

if ( audio.canPlayType &&
     typeof audio.canPlayType == 'function' )
{
    for ( format in test )
    {
        if ( "" != audio.canPlayType( test[format] ) )
        {
            supported.push(format);
        }
    }
}
JavaScript Interfaces




Something for later…
JavaScript Interfaces




Something for later…
if ( window.localStorage )
{
   // Sweet!
}
JavaScript Interfaces




Something for later…
if ( window.localStorage )
{
   var cache = window.localStorage;
   cache.setItem( 'test', 'I am storing nuts for the winter.' );
}
JavaScript Interfaces




Something for later…
JavaScript Interfaces




Something for later…
if ( window.localStorage )
{
   var cache = window.localStorage;
   console.log( cache.getItem('test') );
}
JavaScript Interfaces




Something for later…
if ( window.localStorage )
{
   var cache = window.localStorage;
   console.log( cache.getItem('test') );
   cache.clear();
   console.log( cache.getItem('test') );
}
JavaScript Interfaces




Something for later…
length
The number of items stored.
key( n )
Returns the name of the nth key (or null).
getItem( key )
Returns the value for the given key (or null).
setItem( key, value )
Stores a value for a given key.
JavaScript Interfaces




Local Storage…
…is restricted by domain
…persists until deleted
 (programmatically or by the user)

…is limited in size (usually 5MB)
…is (currently) limited to strings
JavaScript Interfaces




Session storage
…is like local storage
…disappears when the browser is closed
JavaScript Interfaces




Cue the sad trombone
if ( window.localStorage )
{
   var
   cache = window.localStorage,
   obj = {
    one: 1,
    two: 2
   };
   cache.setItem( 'nums', obj );
   console.log( cache.getItem( 'nums' ) );
}
JavaScript Interfaces




Huzzah!
if ( window.localStorage )
{
   var
   cache = window.localStorage,
   obj = {
    one: 1,
    two: 2
   };
   cache.setItem( 'nums', JSON.stringify( obj ) );
   console.log( JSON.parse( cache.getItem( 'nums' ) ) );
}
JavaScript Interfaces




Local Storage…
…is restricted by domain
…persists until deleted
 (programmatically or by the user)

…is limited in size (usually 5MB)
…is (currently) limited to strings
…mutable
JavaScript Interfaces




Whoops!
window.localStorage.setItem( ‘important’, ‘My locker combo is…’ );
                                                                      Script A



window.localStorage.setItem( ‘test’, ‘Just playing around’ );
// …
window.localStorage.clear();
                                                                      Script B
JavaScript Interfaces




Play nicely in the sandbox
// create a Squirrel instance with your unique key
var $S = new Squirrel( 'scale-song' );

// write a value to the cache
$S.write( 'doe', 'ray' );
// read it back
$S.read( 'doe' ); // 'ray'

// write a value to a sub-cache
$S.write( 'song', 'doe', 'a dear, a female dear' );
// read back the original value
$S.read( 'doe' ); // 'ray'
// read back the sub-cached value
$S.read( 'song', 'doe' ); // 'a dear, a female dear'
                                Using Squirrel.js (http://github.com/easy-designs/Squirrel.js)
JavaScript Interfaces




Play nicely in the sandbox
// removing a single property from the sub-cache
$S.remove( 'song', 'doe' );
// try to read the sub-cached value
$S.read( 'song', 'doe' ); // null
// read the root value
$S.read( 'doe' ); // 'ray'
                               Using Squirrel.js (http://github.com/easy-designs/Squirrel.js)
JavaScript Interfaces




Play nicely in the sandbox
// add some more content to the sub-cache
$S.write( 'song', 'doe', 'a dear, a female dear' );
$S.write( 'song', 'ray', 'a drop of golden sun' );
// clear the whole sub-cache
$S.clear( 'song' );
// check that it's been cleared
$S.read( 'song', 'doe' ); // null
$S.read( 'song', 'ray' ); // null
// check that the root value's still intact
$S.read( 'doe' ); // 'ray'
                                 Using Squirrel.js (http://github.com/easy-designs/Squirrel.js)
JavaScript Interfaces




Play nicely in the sandbox
// remove a property form the main cache
$S.remove( 'doe' );
// check it's value
$S.read( 'doe' ); // null

// write a bit more data in the root and in a sub-cache
$S.write( 'doe', 'ray' );
$S.write( 'song', 'doe', 'a dear, a female dear' );
$S.write( 'song', 'ray', 'a drop of golden sun' );

// clear the whole cache
$S.clear();
// check it's all gone
$S.read( 'song', 'doe' ); // null
$S.read( 'song', 'ray' ); // null
$S.read( 'doe' ); // null
                                    Using Squirrel.js (http://github.com/easy-designs/Squirrel.js)
JavaScript Interfaces




When you need a “bigger boat”
JavaScript Interfaces




Example: wikiHow Survival Kit




         http://apps.wikihow.com/survivalkit/
JavaScript Interfaces




How it works
               Page Loads


           Database is created


       SQL is executed to load data


            App is ready to go
JavaScript Interfaces




Inspecting the DB
JavaScript Interfaces




Competing ideas

                             +



                  Indexed DB
JavaScript Interfaces




Unification (eventually)



             Indexed DB
JavaScript Interfaces




Consider

       Kids                 Candy




              Candy Sales
JavaScript Interfaces




Comparison: initialize
var db = window.openDatabase(                 var request = window.indexedDB.open(
  "CandyDB", "",                                "CandyDB", "My candy store database"
  "My candy store database", 1024             );
);
                                                                                  indexedDB
                               Web Database
JavaScript Interfaces




Comparison: initialize                                                           Web Database

if (db.version != "1")
{
  db.changeVersion( db.version, "1", function(tx){
      // Initialize database
      var tables = [
        { name: "kids", columns: ["id INTEGER PRIMARY KEY", "name TEXT"]},
        { name: "candy", columns: ["id INTEGER PRIMARY KEY", "name TEXT"]},
        { name: "candySales", columns: ["kid_id INTEGER", "candy_id INTEGER",
                                         "date TEXT"]} ],
      len = tables.length, table;
      while ( len-- ) {
        table = tables[len];
        tx.executeSql(
          "CREATE TABLE " + table.name + "(" + table.columns.join(", ") + ");"
        );
      }
   },
   null, function(){ loadData(db); } );
}
else {
  // User has been here before, no initialization required.
  loadData(db);
}
JavaScript Interfaces




Comparison: initialize                                                               indexedDB

request.onsuccess = function(event) {
  var db = event.result;
  if (db.version != "1") {
    // Initialize database
    var createdObjectStoreCount = 0,
    objectStores = [ { name: "kids", keyPath: "id", autoIncrement: true },
                      { name: "candy", keyPath: "id", autoIncrement: true },
                      { name: "candySales", keyPath: "", autoIncrement: true } ],
    len = objectStores.length, params;
 
    while ( len-- ) {
      var params = objectStores[len];
      request = db.createObjectStore(
        params.name, params.keyPath, params.autoIncrement
      );
      request.onsuccess = objectStoreCreated;
    }
  }
  else {
    // User has been here before, no initialization required.
    loadData(db);
  }
};
JavaScript Interfaces




Comparison: initialize                                               indexedDB

function objectStoreCreated(event) {
  if ( ++createdObjectStoreCount == objectStores.length )
  {
     db.setVersion("1").onsuccess = function(event) {
       loadData(db);
     };
  }
}
JavaScript Interfaces




Comparison: create                                                                      The Data

var kids = [ { name: "Anna" }, { name: "Betty" }, { name: "Christine" } ];


var db = window.openDatabase(                  var request = window.indexedDB.open(
 "CandyDB", "1",                                 "CandyDB", "My candy store database"
 "My candy store database", 1024);             );
db.transaction( function(tx){                  request.onsuccess = function(e) {
 var i=0, len=kids.length;                       var objectStore = e.result
 while ( i < len )                                                    .objectStore("kids"),
 {                                               var i=0, len=kids.length;
    var kid = kids[i++];                         while ( i < len ) {
    tx.executeSql(                                 var kid = kids[i++];
      "INSERT INTO kids (name) “ +                 objectStore.add(kid)
      “VALUES (:name);", [kid],                                 .onsuccess = function(e) {
      function(tx, results) {                       console.log(
         console.log(                                  "Saved record for " +
            "Saved record for " +                       kid.name + " with id " +
            kid.name + " with id " +                    e.result );
            results.insertId );                    };
      });                                        }
 }                                             };
});
                                                                                      indexedDB
                                Web Database
JavaScript Interfaces




Comparison: simple read
db.readTransaction( function(tx) {            request.onsuccess = function(e) {
 // Enumerate the entire table.                // Enumerate the entire object store.
 tx.executeSql(                                request = e.result
   "SELECT * FROM kids",                                    .objectStore("kids")
   function( tx, results ) {                                .openCursor();
      var rows = results.rows,                 request.onsuccess = function(event) {
      i=0, len=rows.length, item;                var cursor = event.result;
      while ( i < len ) {                        // If cursor is null … done
        item = rows.item(i++);                   if (!cursor) { return; }
        console.log( item.name );                console.log( cursor.value.name );
      }                                          cursor.continue();
    }                                          };
 });                                          };
});
                                                                                  indexedDB
                               Web Database
JavaScript Interfaces




Comparison: joined read                                                      Web Database

db.readTransaction(function(tx) {
 tx.executeSql(
    "SELECT name, COUNT(candySales.kidId) " +
    "FROM kids " +
    "LEFT JOIN candySales ON kids.id = candySales.kidId " +
    "GROUP BY kids.id;",
    function(tx, results) {
      var rows = results.rows, i=0, len=rows.length;
      while ( i<len ) {
        var item = rows.item(i++);
        console.log( item.name + "bought " + item.count + "pieces" );
      }
    });
});
JavaScript Interfaces




Comparison: joined read                                                        indexedDB

var candyEaters = [];
request.onsuccess = function(event) {
  var db = event.result,
  transaction = db.transaction(["kids", "candySales"]);
  transaction.oncomplete = function(){ console.log(candyEaters); },
  kidCursor, saleCursor, salesLoaded=false, count;
 
  var kidsStore = transaction.objectStore("kids");
  kidsStore.openCursor().onsuccess = function(event) {
    kidCursor = event.result;
    count = 0;
    attemptWalk();
  }

 var salesStore = transaction.objectStore("candySales");
 var kidIndex = salesStore.index("kidId");
 kidIndex.openObjectCursor().onsuccess = function(event) {
   saleCursor = event.result;
   salesLoaded = true;
   attemptWalk();
 }

 //…
JavaScript Interfaces




Comparison: joined read                                                              indexedDB

    // …

    function attemptWalk() {
      if (!kidCursor || !salesLoaded) return;
 
        if ( saleCursor && kidCursor.value.id == saleCursor.kidId )
        {
          count++;
          saleCursor.continue();
        }
        else
        {
          candyEaters.push({ name: kidCursor.value.name, count: count });
          kidCursor.continue();
        }
    }

} // end request.onsuccess
JavaScript Interfaces




In the wikiHow app…
          Categories

                  A NY
                         HA
                           VE
                                                Badges
             E   M              MA
        H AV                      NY



   Articles                     Questions        Quiz
                                                Results
          Content
           Content
            Content                         User Triggered

         Preloaded
JavaScript Interfaces




Where am I?
JavaScript Interfaces




Geolocation API
if ( navigator.geolocation )
{
  navigator.geolocation.getCurrentPosition(
    function(position){
      console.log( position.coords );
    },
    function(error){
      alert('ouch');
    }
  );
}
JavaScript Interfaces




What’s in a name?
function getPlaceFromFlickr( lat, lon, callback )
{
  // the YQL statement
  var yql = 'select * from flickr.places where lat=' +
            lat + ' and lon=' + lon;

 // assembling the YQL webservice API
 var url = 'http://query.yahooapis.com/v1/public/yql?q=' +
           encodeURIComponent(yql) +
           '&format=json&diagnostics=false&callback=' + callback;

 // create a new script node and add it to the document
 var s = document.createElement('script');
 s.setAttribute( 'src', url );
 document.getElementsByTagName('head')[0].appendChild(s);
};

// …
JavaScript Interfaces




What’s in a name?
// callback in case there is a place found
function output(o){
  if ( typeof(o.query.results.places.place) != 'undefined' )
  {
    console.log( o.query.results.places.place.name );
  }
}
JavaScript Interfaces




What’s in a name?
if ( navigator.geolocation )
{
  navigator.geolocation.getCurrentPosition(
    function(position){
      getPlaceFromFlickr(
        position.coords.latitude,
        position.coords.longitude,
        'output'
      );
    },
    function(error){
      alert('ouch');
    }
  );
}
JavaScript Interfaces




Bonus: Offline Cache
CACHE MANIFEST
# Cache manifest version 1.0
# Change the version number to trigger an update
index.php
c/main.css
j/main.js
i/logo.png

NETWORK:
live-feed.php
rss.json
                                    cache.manifest   served with MIME of text/cache-manifest


<html manifest="cache.manifest">


navigator.onLine // true or false
JavaScript Interfaces




             Slides available at
  http://slideshare.net/AaronGustafson

     This presentation is licensed under
             Creative Commons
Attribution-Noncommercial-Share Alike 3.0

          flickr Photo Credits
          “HTML5 logo in Braille” by Ted Drake
         “Dual Samsung Monitors” by steve-uk
                “Statue of Liberty” by gadl
                   “Lego” by DavePress
            “iFlickr touch screen” by exfordy
               “Green Plant” by kevin1024

More Related Content

What's hot

Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Masahiro Nagano
 
High Performance XQuery Processing in PHP with Zorba by Vikram Vaswani
High Performance XQuery Processing in PHP with Zorba by Vikram VaswaniHigh Performance XQuery Processing in PHP with Zorba by Vikram Vaswani
High Performance XQuery Processing in PHP with Zorba by Vikram Vaswanivvaswani
 
Harmonious Development: Standardizing The Deployment Process via Vagrant and ...
Harmonious Development: Standardizing The Deployment Process via Vagrant and ...Harmonious Development: Standardizing The Deployment Process via Vagrant and ...
Harmonious Development: Standardizing The Deployment Process via Vagrant and ...Acquia
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Node.js in action
Node.js in actionNode.js in action
Node.js in actionSimon Su
 
Mongo db mug_2012-02-07
Mongo db mug_2012-02-07Mongo db mug_2012-02-07
Mongo db mug_2012-02-07Will Button
 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperJonathan Wage
 
JavaScript & HTML5 - Brave New World
JavaScript & HTML5 - Brave New WorldJavaScript & HTML5 - Brave New World
JavaScript & HTML5 - Brave New WorldRobert Nyman
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Web::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPWeb::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPMichael Francis
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Designunodelostrece
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMJonathan Wage
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMJonathan Wage
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using RoomNelson Glauber Leal
 
Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)err
 
Stanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet ModulesStanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet ModulesPuppet
 
Puppet Camp DC 2015: Stop Writing Puppet Modules: A Guide to Best Practices i...
Puppet Camp DC 2015: Stop Writing Puppet Modules: A Guide to Best Practices i...Puppet Camp DC 2015: Stop Writing Puppet Modules: A Guide to Best Practices i...
Puppet Camp DC 2015: Stop Writing Puppet Modules: A Guide to Best Practices i...Puppet
 
神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)guregu
 
Drush - use full power - DrupalCamp Donetsk 2014
Drush - use full power - DrupalCamp Donetsk 2014Drush - use full power - DrupalCamp Donetsk 2014
Drush - use full power - DrupalCamp Donetsk 2014Alex S
 
Windows Azure Storage & Sql Azure
Windows Azure Storage & Sql AzureWindows Azure Storage & Sql Azure
Windows Azure Storage & Sql AzureMaarten Balliauw
 

What's hot (20)

Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
 
High Performance XQuery Processing in PHP with Zorba by Vikram Vaswani
High Performance XQuery Processing in PHP with Zorba by Vikram VaswaniHigh Performance XQuery Processing in PHP with Zorba by Vikram Vaswani
High Performance XQuery Processing in PHP with Zorba by Vikram Vaswani
 
Harmonious Development: Standardizing The Deployment Process via Vagrant and ...
Harmonious Development: Standardizing The Deployment Process via Vagrant and ...Harmonious Development: Standardizing The Deployment Process via Vagrant and ...
Harmonious Development: Standardizing The Deployment Process via Vagrant and ...
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Node.js in action
Node.js in actionNode.js in action
Node.js in action
 
Mongo db mug_2012-02-07
Mongo db mug_2012-02-07Mongo db mug_2012-02-07
Mongo db mug_2012-02-07
 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
 
JavaScript & HTML5 - Brave New World
JavaScript & HTML5 - Brave New WorldJavaScript & HTML5 - Brave New World
JavaScript & HTML5 - Brave New World
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Web::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPWeb::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTP
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Design
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODM
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODM
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using Room
 
Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)
 
Stanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet ModulesStanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet Modules
 
Puppet Camp DC 2015: Stop Writing Puppet Modules: A Guide to Best Practices i...
Puppet Camp DC 2015: Stop Writing Puppet Modules: A Guide to Best Practices i...Puppet Camp DC 2015: Stop Writing Puppet Modules: A Guide to Best Practices i...
Puppet Camp DC 2015: Stop Writing Puppet Modules: A Guide to Best Practices i...
 
神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)
 
Drush - use full power - DrupalCamp Donetsk 2014
Drush - use full power - DrupalCamp Donetsk 2014Drush - use full power - DrupalCamp Donetsk 2014
Drush - use full power - DrupalCamp Donetsk 2014
 
Windows Azure Storage & Sql Azure
Windows Azure Storage & Sql AzureWindows Azure Storage & Sql Azure
Windows Azure Storage & Sql Azure
 

Similar to HTML5 JavaScript Interfaces

JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011Nick Sieger
 
Web Development Study Jam #2 _ Basic JavaScript.pptx
Web Development Study Jam #2 _ Basic JavaScript.pptxWeb Development Study Jam #2 _ Basic JavaScript.pptx
Web Development Study Jam #2 _ Basic JavaScript.pptxSekarMaduKusumawarda1
 
CoffeeScript Design Patterns
CoffeeScript Design PatternsCoffeeScript Design Patterns
CoffeeScript Design PatternsTrevorBurnham
 
Asynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingAsynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingSteve Rhoades
 
Terrastore - A document database for developers
Terrastore - A document database for developersTerrastore - A document database for developers
Terrastore - A document database for developersSergio Bossa
 
Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)Bozhidar Batsov
 
Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012alexismidon
 
Building Go Web Apps
Building Go Web AppsBuilding Go Web Apps
Building Go Web AppsMark
 

Similar to HTML5 JavaScript Interfaces (20)

Play á la Rails
Play á la RailsPlay á la Rails
Play á la Rails
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
Web Development Study Jam #2 _ Basic JavaScript.pptx
Web Development Study Jam #2 _ Basic JavaScript.pptxWeb Development Study Jam #2 _ Basic JavaScript.pptx
Web Development Study Jam #2 _ Basic JavaScript.pptx
 
JavaScript Neednt Hurt - JavaBin talk
JavaScript Neednt Hurt - JavaBin talkJavaScript Neednt Hurt - JavaBin talk
JavaScript Neednt Hurt - JavaBin talk
 
CoffeeScript Design Patterns
CoffeeScript Design PatternsCoffeeScript Design Patterns
CoffeeScript Design Patterns
 
Node.js
Node.jsNode.js
Node.js
 
Asynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingAsynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time Messaging
 
Terrastore - A document database for developers
Terrastore - A document database for developersTerrastore - A document database for developers
Terrastore - A document database for developers
 
Play framework
Play frameworkPlay framework
Play framework
 
Sprockets
SprocketsSprockets
Sprockets
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)
 
Jet presentation
Jet presentationJet presentation
Jet presentation
 
Node.js - A Quick Tour
Node.js - A Quick TourNode.js - A Quick Tour
Node.js - A Quick Tour
 
Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012
 
Latinoware
LatinowareLatinoware
Latinoware
 
Building Go Web Apps
Building Go Web AppsBuilding Go Web Apps
Building Go Web Apps
 
Javascript status 2016
Javascript status 2016Javascript status 2016
Javascript status 2016
 
How to React Native
How to React NativeHow to React Native
How to React Native
 
"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues
 

More from Aaron Gustafson

Delivering Critical Information and Services [JavaScript & Friends 2021]
Delivering Critical Information and Services [JavaScript & Friends 2021]Delivering Critical Information and Services [JavaScript & Friends 2021]
Delivering Critical Information and Services [JavaScript & Friends 2021]Aaron Gustafson
 
Adapting to Reality [Guest Lecture, March 2021]
Adapting to Reality [Guest Lecture, March 2021]Adapting to Reality [Guest Lecture, March 2021]
Adapting to Reality [Guest Lecture, March 2021]Aaron Gustafson
 
Designing the Conversation [Beyond Tellerrand 2019]
Designing the Conversation [Beyond Tellerrand 2019]Designing the Conversation [Beyond Tellerrand 2019]
Designing the Conversation [Beyond Tellerrand 2019]Aaron Gustafson
 
Getting Started with Progressive Web Apps [Beyond Tellerrand 2019]
Getting Started with Progressive Web Apps [Beyond Tellerrand 2019]Getting Started with Progressive Web Apps [Beyond Tellerrand 2019]
Getting Started with Progressive Web Apps [Beyond Tellerrand 2019]Aaron Gustafson
 
Progressive Web Apps: Where Do I Begin?
Progressive Web Apps: Where Do I Begin?Progressive Web Apps: Where Do I Begin?
Progressive Web Apps: Where Do I Begin?Aaron Gustafson
 
Media in the Age of PWAs [ImageCon 2019]
Media in the Age of PWAs [ImageCon 2019]Media in the Age of PWAs [ImageCon 2019]
Media in the Age of PWAs [ImageCon 2019]Aaron Gustafson
 
Adapting to Reality [Starbucks Lunch & Learn]
Adapting to Reality [Starbucks Lunch & Learn]Adapting to Reality [Starbucks Lunch & Learn]
Adapting to Reality [Starbucks Lunch & Learn]Aaron Gustafson
 
Conversational Semantics for the Web [CascadiaJS 2018]
Conversational Semantics for the Web [CascadiaJS 2018]Conversational Semantics for the Web [CascadiaJS 2018]
Conversational Semantics for the Web [CascadiaJS 2018]Aaron Gustafson
 
Better Performance === Greater Accessibility [Inclusive Design 24 2018]
Better Performance === Greater Accessibility [Inclusive Design 24 2018]Better Performance === Greater Accessibility [Inclusive Design 24 2018]
Better Performance === Greater Accessibility [Inclusive Design 24 2018]Aaron Gustafson
 
PWA: Where Do I Begin? [Microsoft Ignite 2018]
PWA: Where Do I Begin? [Microsoft Ignite 2018]PWA: Where Do I Begin? [Microsoft Ignite 2018]
PWA: Where Do I Begin? [Microsoft Ignite 2018]Aaron Gustafson
 
Designing the Conversation [Concatenate 2018]
Designing the Conversation [Concatenate 2018]Designing the Conversation [Concatenate 2018]
Designing the Conversation [Concatenate 2018]Aaron Gustafson
 
Designing the Conversation [Accessibility DC 2018]
Designing the Conversation [Accessibility DC 2018]Designing the Conversation [Accessibility DC 2018]
Designing the Conversation [Accessibility DC 2018]Aaron Gustafson
 
Performance as User Experience [AEADC 2018]
Performance as User Experience [AEADC 2018]Performance as User Experience [AEADC 2018]
Performance as User Experience [AEADC 2018]Aaron Gustafson
 
The Web Should Just Work for Everyone
The Web Should Just Work for EveryoneThe Web Should Just Work for Everyone
The Web Should Just Work for EveryoneAaron Gustafson
 
Performance as User Experience [AEA SEA 2018]
Performance as User Experience [AEA SEA 2018]Performance as User Experience [AEA SEA 2018]
Performance as User Experience [AEA SEA 2018]Aaron Gustafson
 
Performance as User Experience [An Event Apart Denver 2017]
Performance as User Experience [An Event Apart Denver 2017]Performance as User Experience [An Event Apart Denver 2017]
Performance as User Experience [An Event Apart Denver 2017]Aaron Gustafson
 
Advanced Design Methods 1, Day 2
Advanced Design Methods 1, Day 2Advanced Design Methods 1, Day 2
Advanced Design Methods 1, Day 2Aaron Gustafson
 
Advanced Design Methods 1, Day 1
Advanced Design Methods 1, Day 1Advanced Design Methods 1, Day 1
Advanced Design Methods 1, Day 1Aaron Gustafson
 
Designing the Conversation [Paris Web 2017]
Designing the Conversation [Paris Web 2017]Designing the Conversation [Paris Web 2017]
Designing the Conversation [Paris Web 2017]Aaron Gustafson
 
Exploring Adaptive Interfaces [Generate 2017]
Exploring Adaptive Interfaces [Generate 2017]Exploring Adaptive Interfaces [Generate 2017]
Exploring Adaptive Interfaces [Generate 2017]Aaron Gustafson
 

More from Aaron Gustafson (20)

Delivering Critical Information and Services [JavaScript & Friends 2021]
Delivering Critical Information and Services [JavaScript & Friends 2021]Delivering Critical Information and Services [JavaScript & Friends 2021]
Delivering Critical Information and Services [JavaScript & Friends 2021]
 
Adapting to Reality [Guest Lecture, March 2021]
Adapting to Reality [Guest Lecture, March 2021]Adapting to Reality [Guest Lecture, March 2021]
Adapting to Reality [Guest Lecture, March 2021]
 
Designing the Conversation [Beyond Tellerrand 2019]
Designing the Conversation [Beyond Tellerrand 2019]Designing the Conversation [Beyond Tellerrand 2019]
Designing the Conversation [Beyond Tellerrand 2019]
 
Getting Started with Progressive Web Apps [Beyond Tellerrand 2019]
Getting Started with Progressive Web Apps [Beyond Tellerrand 2019]Getting Started with Progressive Web Apps [Beyond Tellerrand 2019]
Getting Started with Progressive Web Apps [Beyond Tellerrand 2019]
 
Progressive Web Apps: Where Do I Begin?
Progressive Web Apps: Where Do I Begin?Progressive Web Apps: Where Do I Begin?
Progressive Web Apps: Where Do I Begin?
 
Media in the Age of PWAs [ImageCon 2019]
Media in the Age of PWAs [ImageCon 2019]Media in the Age of PWAs [ImageCon 2019]
Media in the Age of PWAs [ImageCon 2019]
 
Adapting to Reality [Starbucks Lunch & Learn]
Adapting to Reality [Starbucks Lunch & Learn]Adapting to Reality [Starbucks Lunch & Learn]
Adapting to Reality [Starbucks Lunch & Learn]
 
Conversational Semantics for the Web [CascadiaJS 2018]
Conversational Semantics for the Web [CascadiaJS 2018]Conversational Semantics for the Web [CascadiaJS 2018]
Conversational Semantics for the Web [CascadiaJS 2018]
 
Better Performance === Greater Accessibility [Inclusive Design 24 2018]
Better Performance === Greater Accessibility [Inclusive Design 24 2018]Better Performance === Greater Accessibility [Inclusive Design 24 2018]
Better Performance === Greater Accessibility [Inclusive Design 24 2018]
 
PWA: Where Do I Begin? [Microsoft Ignite 2018]
PWA: Where Do I Begin? [Microsoft Ignite 2018]PWA: Where Do I Begin? [Microsoft Ignite 2018]
PWA: Where Do I Begin? [Microsoft Ignite 2018]
 
Designing the Conversation [Concatenate 2018]
Designing the Conversation [Concatenate 2018]Designing the Conversation [Concatenate 2018]
Designing the Conversation [Concatenate 2018]
 
Designing the Conversation [Accessibility DC 2018]
Designing the Conversation [Accessibility DC 2018]Designing the Conversation [Accessibility DC 2018]
Designing the Conversation [Accessibility DC 2018]
 
Performance as User Experience [AEADC 2018]
Performance as User Experience [AEADC 2018]Performance as User Experience [AEADC 2018]
Performance as User Experience [AEADC 2018]
 
The Web Should Just Work for Everyone
The Web Should Just Work for EveryoneThe Web Should Just Work for Everyone
The Web Should Just Work for Everyone
 
Performance as User Experience [AEA SEA 2018]
Performance as User Experience [AEA SEA 2018]Performance as User Experience [AEA SEA 2018]
Performance as User Experience [AEA SEA 2018]
 
Performance as User Experience [An Event Apart Denver 2017]
Performance as User Experience [An Event Apart Denver 2017]Performance as User Experience [An Event Apart Denver 2017]
Performance as User Experience [An Event Apart Denver 2017]
 
Advanced Design Methods 1, Day 2
Advanced Design Methods 1, Day 2Advanced Design Methods 1, Day 2
Advanced Design Methods 1, Day 2
 
Advanced Design Methods 1, Day 1
Advanced Design Methods 1, Day 1Advanced Design Methods 1, Day 1
Advanced Design Methods 1, Day 1
 
Designing the Conversation [Paris Web 2017]
Designing the Conversation [Paris Web 2017]Designing the Conversation [Paris Web 2017]
Designing the Conversation [Paris Web 2017]
 
Exploring Adaptive Interfaces [Generate 2017]
Exploring Adaptive Interfaces [Generate 2017]Exploring Adaptive Interfaces [Generate 2017]
Exploring Adaptive Interfaces [Generate 2017]
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxFIDO Alliance
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfdanishmna97
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistandanishmna97
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsLeah Henrickson
 
Quantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation ComputingQuantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation ComputingWSO2
 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewDianaGray10
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxFIDO Alliance
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityVictorSzoltysek
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptxFIDO Alliance
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch TuesdayIvanti
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Paige Cruz
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMKumar Satyam
 
Navigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern EnterpriseNavigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern EnterpriseWSO2
 
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAnitaRaj43
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 

Recently uploaded (20)

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptx
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cf
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
 
Quantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation ComputingQuantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation Computing
 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overview
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps Productivity
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch Tuesday
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
Navigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern EnterpriseNavigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern Enterprise
 
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 

HTML5 JavaScript Interfaces

  • 1. JavaScript Interfaces in HTML5 Aaron Gustafson Easy Designs, LLC slideshare.net/AaronGustafson
  • 3. JavaScript Interfaces Working with media <audio controls="controls" autobuffer="autobuffer" preload="auto"> <source src="my.mp3"/> <source src="my.oga"/> <ul> <li><a href="my.mp3">Download as audio/mp3</a></li> <li><a href="my.oga">Download as audio/ogg</a></li> </ul> </audio>
  • 4. JavaScript Interfaces Roll your own player $('audio').each(function(){ var audio = this, $button = $('<button>Play</button>') .click(function(){ audio.play(); }); $(this) .removeAttr('controls') .after($button); }); Using jQuery
  • 5. JavaScript Interfaces Roll your own currentSrc Returns the address of the current media resource (or empty). networkState Returns a number (0-3) to indicate the network activity of the element: 0 = not initialized 1 = initialized, but idle 2 = actively downloading 3 = no resource buffered Returns a TimeRange for what’s been buffered by the browser. duration Returns the length (in seconds) of the media object, NaN when resource isn’t found. currentTime Current playback position (in seconds). Can be set to seek a time. initialTime Returns the initial (possibly sought) playback position when the resource was loaded.
  • 6. JavaScript Interfaces Roll your own readyState A numeric value (0-4) representing the current state of the element: 0 = no information available 1 = metadata received 2 = have current data, but not enough to do anything yet 3 = have a little future data, but not a lot 4 = have enough data to advance without risking a stop (at the default playback rate). paused Returns true or false based on the state of the media. ended Returns true if playback has reached the end of the media resource. playbackRate Returns the current playback rate (usually 1.0), but is also settable. defaultPlaybackRate Returns the default playback rate (usually 1.0), but is also settable.
  • 7. JavaScript Interfaces Roll your own played Returns a TimeRange object that tells how much of the media resource has been played. load() Triggers the reset and restart of a media resource. play() Plays the audio. pause() Pauses the audio. canPlayType( type ) Returns “probably,” “maybe” or empty (for no) based on how confident the browser is. seeking Returns true if the user agent is currently seeking. seekable Returns a TimeRange object that represents the “seekable” area of the media resource.
  • 8. JavaScript Interfaces Test for native support var audio = document.createElement('audio'), test = { mp3: 'audio/mpeg', oga: 'audio/ogg; codecs="vorbis"' }, supported = []; if ( audio.canPlayType && typeof audio.canPlayType == 'function' ) { for ( format in test ) { if ( "" != audio.canPlayType( test[format] ) ) { supported.push(format); } } }
  • 10. JavaScript Interfaces Something for later… if ( window.localStorage ) { // Sweet! }
  • 11. JavaScript Interfaces Something for later… if ( window.localStorage ) { var cache = window.localStorage; cache.setItem( 'test', 'I am storing nuts for the winter.' ); }
  • 13. JavaScript Interfaces Something for later… if ( window.localStorage ) { var cache = window.localStorage; console.log( cache.getItem('test') ); }
  • 14. JavaScript Interfaces Something for later… if ( window.localStorage ) { var cache = window.localStorage; console.log( cache.getItem('test') ); cache.clear(); console.log( cache.getItem('test') ); }
  • 15. JavaScript Interfaces Something for later… length The number of items stored. key( n ) Returns the name of the nth key (or null). getItem( key ) Returns the value for the given key (or null). setItem( key, value ) Stores a value for a given key.
  • 16. JavaScript Interfaces Local Storage… …is restricted by domain …persists until deleted (programmatically or by the user) …is limited in size (usually 5MB) …is (currently) limited to strings
  • 17. JavaScript Interfaces Session storage …is like local storage …disappears when the browser is closed
  • 18. JavaScript Interfaces Cue the sad trombone if ( window.localStorage ) { var cache = window.localStorage, obj = { one: 1, two: 2 }; cache.setItem( 'nums', obj ); console.log( cache.getItem( 'nums' ) ); }
  • 19. JavaScript Interfaces Huzzah! if ( window.localStorage ) { var cache = window.localStorage, obj = { one: 1, two: 2 }; cache.setItem( 'nums', JSON.stringify( obj ) ); console.log( JSON.parse( cache.getItem( 'nums' ) ) ); }
  • 20. JavaScript Interfaces Local Storage… …is restricted by domain …persists until deleted (programmatically or by the user) …is limited in size (usually 5MB) …is (currently) limited to strings …mutable
  • 21. JavaScript Interfaces Whoops! window.localStorage.setItem( ‘important’, ‘My locker combo is…’ ); Script A window.localStorage.setItem( ‘test’, ‘Just playing around’ ); // … window.localStorage.clear(); Script B
  • 22. JavaScript Interfaces Play nicely in the sandbox // create a Squirrel instance with your unique key var $S = new Squirrel( 'scale-song' ); // write a value to the cache $S.write( 'doe', 'ray' ); // read it back $S.read( 'doe' ); // 'ray' // write a value to a sub-cache $S.write( 'song', 'doe', 'a dear, a female dear' ); // read back the original value $S.read( 'doe' ); // 'ray' // read back the sub-cached value $S.read( 'song', 'doe' ); // 'a dear, a female dear' Using Squirrel.js (http://github.com/easy-designs/Squirrel.js)
  • 23. JavaScript Interfaces Play nicely in the sandbox // removing a single property from the sub-cache $S.remove( 'song', 'doe' ); // try to read the sub-cached value $S.read( 'song', 'doe' ); // null // read the root value $S.read( 'doe' ); // 'ray' Using Squirrel.js (http://github.com/easy-designs/Squirrel.js)
  • 24. JavaScript Interfaces Play nicely in the sandbox // add some more content to the sub-cache $S.write( 'song', 'doe', 'a dear, a female dear' ); $S.write( 'song', 'ray', 'a drop of golden sun' ); // clear the whole sub-cache $S.clear( 'song' ); // check that it's been cleared $S.read( 'song', 'doe' ); // null $S.read( 'song', 'ray' ); // null // check that the root value's still intact $S.read( 'doe' ); // 'ray' Using Squirrel.js (http://github.com/easy-designs/Squirrel.js)
  • 25. JavaScript Interfaces Play nicely in the sandbox // remove a property form the main cache $S.remove( 'doe' ); // check it's value $S.read( 'doe' ); // null // write a bit more data in the root and in a sub-cache $S.write( 'doe', 'ray' ); $S.write( 'song', 'doe', 'a dear, a female dear' ); $S.write( 'song', 'ray', 'a drop of golden sun' ); // clear the whole cache $S.clear(); // check it's all gone $S.read( 'song', 'doe' ); // null $S.read( 'song', 'ray' ); // null $S.read( 'doe' ); // null Using Squirrel.js (http://github.com/easy-designs/Squirrel.js)
  • 26. JavaScript Interfaces When you need a “bigger boat”
  • 27. JavaScript Interfaces Example: wikiHow Survival Kit http://apps.wikihow.com/survivalkit/
  • 28. JavaScript Interfaces How it works Page Loads Database is created SQL is executed to load data App is ready to go
  • 32. JavaScript Interfaces Consider Kids Candy Candy Sales
  • 33. JavaScript Interfaces Comparison: initialize var db = window.openDatabase( var request = window.indexedDB.open( "CandyDB", "", "CandyDB", "My candy store database" "My candy store database", 1024 ); ); indexedDB Web Database
  • 34. JavaScript Interfaces Comparison: initialize Web Database if (db.version != "1") { db.changeVersion( db.version, "1", function(tx){ // Initialize database var tables = [ { name: "kids", columns: ["id INTEGER PRIMARY KEY", "name TEXT"]}, { name: "candy", columns: ["id INTEGER PRIMARY KEY", "name TEXT"]}, { name: "candySales", columns: ["kid_id INTEGER", "candy_id INTEGER", "date TEXT"]} ],   len = tables.length, table; while ( len-- ) { table = tables[len]; tx.executeSql( "CREATE TABLE " + table.name + "(" + table.columns.join(", ") + ");" ); } }, null, function(){ loadData(db); } ); } else { // User has been here before, no initialization required. loadData(db); }
  • 35. JavaScript Interfaces Comparison: initialize indexedDB request.onsuccess = function(event) { var db = event.result; if (db.version != "1") { // Initialize database var createdObjectStoreCount = 0, objectStores = [ { name: "kids", keyPath: "id", autoIncrement: true }, { name: "candy", keyPath: "id", autoIncrement: true }, { name: "candySales", keyPath: "", autoIncrement: true } ], len = objectStores.length, params;   while ( len-- ) { var params = objectStores[len]; request = db.createObjectStore( params.name, params.keyPath, params.autoIncrement ); request.onsuccess = objectStoreCreated; } } else { // User has been here before, no initialization required. loadData(db); } };
  • 36. JavaScript Interfaces Comparison: initialize indexedDB function objectStoreCreated(event) { if ( ++createdObjectStoreCount == objectStores.length ) { db.setVersion("1").onsuccess = function(event) { loadData(db); }; } }
  • 37. JavaScript Interfaces Comparison: create The Data var kids = [ { name: "Anna" }, { name: "Betty" }, { name: "Christine" } ]; var db = window.openDatabase( var request = window.indexedDB.open( "CandyDB", "1", "CandyDB", "My candy store database" "My candy store database", 1024); ); db.transaction( function(tx){ request.onsuccess = function(e) { var i=0, len=kids.length; var objectStore = e.result while ( i < len ) .objectStore("kids"), { var i=0, len=kids.length; var kid = kids[i++]; while ( i < len ) { tx.executeSql( var kid = kids[i++]; "INSERT INTO kids (name) “ + objectStore.add(kid) “VALUES (:name);", [kid], .onsuccess = function(e) { function(tx, results) { console.log( console.log( "Saved record for " + "Saved record for " + kid.name + " with id " + kid.name + " with id " + e.result ); results.insertId ); }; }); } } }; }); indexedDB Web Database
  • 38. JavaScript Interfaces Comparison: simple read db.readTransaction( function(tx) { request.onsuccess = function(e) { // Enumerate the entire table. // Enumerate the entire object store. tx.executeSql( request = e.result "SELECT * FROM kids", .objectStore("kids") function( tx, results ) { .openCursor(); var rows = results.rows, request.onsuccess = function(event) { i=0, len=rows.length, item; var cursor = event.result; while ( i < len ) { // If cursor is null … done item = rows.item(i++); if (!cursor) { return; } console.log( item.name ); console.log( cursor.value.name ); } cursor.continue(); } }; }); }; }); indexedDB Web Database
  • 39. JavaScript Interfaces Comparison: joined read Web Database db.readTransaction(function(tx) { tx.executeSql( "SELECT name, COUNT(candySales.kidId) " + "FROM kids " + "LEFT JOIN candySales ON kids.id = candySales.kidId " + "GROUP BY kids.id;", function(tx, results) { var rows = results.rows, i=0, len=rows.length; while ( i<len ) { var item = rows.item(i++); console.log( item.name + "bought " + item.count + "pieces" ); } }); });
  • 40. JavaScript Interfaces Comparison: joined read indexedDB var candyEaters = []; request.onsuccess = function(event) { var db = event.result, transaction = db.transaction(["kids", "candySales"]); transaction.oncomplete = function(){ console.log(candyEaters); }, kidCursor, saleCursor, salesLoaded=false, count;   var kidsStore = transaction.objectStore("kids"); kidsStore.openCursor().onsuccess = function(event) { kidCursor = event.result; count = 0; attemptWalk(); } var salesStore = transaction.objectStore("candySales"); var kidIndex = salesStore.index("kidId"); kidIndex.openObjectCursor().onsuccess = function(event) { saleCursor = event.result; salesLoaded = true; attemptWalk(); } //…
  • 41. JavaScript Interfaces Comparison: joined read indexedDB // … function attemptWalk() { if (!kidCursor || !salesLoaded) return;   if ( saleCursor && kidCursor.value.id == saleCursor.kidId ) { count++; saleCursor.continue(); } else { candyEaters.push({ name: kidCursor.value.name, count: count }); kidCursor.continue(); } } } // end request.onsuccess
  • 42. JavaScript Interfaces In the wikiHow app… Categories A NY HA VE Badges E M MA H AV NY Articles Questions Quiz Results Content Content Content User Triggered Preloaded
  • 44. JavaScript Interfaces Geolocation API if ( navigator.geolocation ) { navigator.geolocation.getCurrentPosition( function(position){ console.log( position.coords ); }, function(error){ alert('ouch'); } ); }
  • 45. JavaScript Interfaces What’s in a name? function getPlaceFromFlickr( lat, lon, callback ) { // the YQL statement var yql = 'select * from flickr.places where lat=' + lat + ' and lon=' + lon; // assembling the YQL webservice API var url = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent(yql) + '&format=json&diagnostics=false&callback=' + callback; // create a new script node and add it to the document var s = document.createElement('script'); s.setAttribute( 'src', url ); document.getElementsByTagName('head')[0].appendChild(s); }; // …
  • 46. JavaScript Interfaces What’s in a name? // callback in case there is a place found function output(o){ if ( typeof(o.query.results.places.place) != 'undefined' ) { console.log( o.query.results.places.place.name ); } }
  • 47. JavaScript Interfaces What’s in a name? if ( navigator.geolocation ) { navigator.geolocation.getCurrentPosition( function(position){ getPlaceFromFlickr( position.coords.latitude, position.coords.longitude, 'output' ); }, function(error){ alert('ouch'); } ); }
  • 48. JavaScript Interfaces Bonus: Offline Cache CACHE MANIFEST # Cache manifest version 1.0 # Change the version number to trigger an update index.php c/main.css j/main.js i/logo.png NETWORK: live-feed.php rss.json cache.manifest served with MIME of text/cache-manifest <html manifest="cache.manifest"> navigator.onLine // true or false
  • 49. JavaScript Interfaces Slides available at http://slideshare.net/AaronGustafson This presentation is licensed under Creative Commons Attribution-Noncommercial-Share Alike 3.0 flickr Photo Credits “HTML5 logo in Braille” by Ted Drake “Dual Samsung Monitors” by steve-uk “Statue of Liberty” by gadl “Lego” by DavePress “iFlickr touch screen” by exfordy “Green Plant” by kevin1024