SlideShare a Scribd company logo
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

PDF
Testing Web Applications with GEB
PDF
Perl object ?
PDF
Backbone.js: Run your Application Inside The Browser
PDF
4069180 Caching Performance Lessons From Facebook
PDF
Introduction to Nodejs
PDF
From mysql to MongoDB(MongoDB2011北京交流会)
PDF
Drush. Secrets come out.
PDF
PHP 5.3 and Lithium: the most rad php framework
Testing Web Applications with GEB
Perl object ?
Backbone.js: Run your Application Inside The Browser
4069180 Caching Performance Lessons From Facebook
Introduction to Nodejs
From mysql to MongoDB(MongoDB2011北京交流会)
Drush. Secrets come out.
PHP 5.3 and Lithium: the most rad php framework

What's hot (20)

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

Similar to HTML5 JavaScript Interfaces (20)

PDF
Play á la Rails
PDF
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
PPTX
Web Development Study Jam #2 _ Basic JavaScript.pptx
KEY
JavaScript Neednt Hurt - JavaBin talk
PDF
CoffeeScript Design Patterns
KEY
Node.js
PDF
Asynchronous PHP and Real-time Messaging
PDF
Terrastore - A document database for developers
PDF
Play framework
KEY
PDF
Play vs Rails
PDF
Модерни езици за програмиране за JVM (2011)
PPT
Jet presentation
PDF
Node.js - A Quick Tour
PDF
Buildr In Action @devoxx france 2012
PDF
Latinoware
PDF
Building Go Web Apps
PDF
Javascript status 2016
PDF
How to React Native
Play á la Rails
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
Web Development Study Jam #2 _ Basic JavaScript.pptx
JavaScript Neednt Hurt - JavaBin talk
CoffeeScript Design Patterns
Node.js
Asynchronous PHP and Real-time Messaging
Terrastore - A document database for developers
Play framework
Play vs Rails
Модерни езици за програмиране за JVM (2011)
Jet presentation
Node.js - A Quick Tour
Buildr In Action @devoxx france 2012
Latinoware
Building Go Web Apps
Javascript status 2016
How to React Native
Ad

More from Aaron Gustafson (20)

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

Recently uploaded (20)

PDF
Approach and Philosophy of On baking technology
PDF
Electronic commerce courselecture one. Pdf
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Encapsulation theory and applications.pdf
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
Spectroscopy.pptx food analysis technology
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
cuic standard and advanced reporting.pdf
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PPTX
Group 1 Presentation -Planning and Decision Making .pptx
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Approach and Philosophy of On baking technology
Electronic commerce courselecture one. Pdf
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Digital-Transformation-Roadmap-for-Companies.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Encapsulation theory and applications.pdf
NewMind AI Weekly Chronicles - August'25-Week II
“AI and Expert System Decision Support & Business Intelligence Systems”
Reach Out and Touch Someone: Haptics and Empathic Computing
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
Building Integrated photovoltaic BIPV_UPV.pdf
Spectroscopy.pptx food analysis technology
Per capita expenditure prediction using model stacking based on satellite ima...
Unlocking AI with Model Context Protocol (MCP)
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
cuic standard and advanced reporting.pdf
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Group 1 Presentation -Planning and Decision Making .pptx
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf

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