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

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusZilliz
 
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
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 

Recently uploaded (20)

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
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
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 

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