localStorage.foo = "bar";
console.log(localStorage.foo); // "bar"
localStorage.clear();
console.log(localStorage.foo); // ""
localStorage.bar = "baz";
localStorage["mo"] = "zilla";
console.log(localStorage.length); // 2
console.log(localStorage.keys); // ["baz", "mo"]
StorageEvent
Much more complex than Web Storage, being based around asynchronous transactions.
var request = window.indexedDB.open("myDatabase", /* optional version number */ 1);
request.onsuccesss = function(event) { /* db handle in request.result */ };
request.onerror = function(event) { /* specific error in event.target.errorCode */ };
// Create an objectStore to hold information about our customers. We're
// going to use "ssn" as our key path because it's guaranteed to be
// unique.
var objectStore = db.createObjectStore("customers", { keyPath: "ssn" });
// Create an index to search customers by name. We may have duplicates
// so we can't use a unique index.
objectStore.createIndex("name", "name", { unique: false });
// Create an index to search customers by email. We want to ensure that
// no two customers have the same email, so use a unique index.
objectStore.createIndex("email", "email", { unique: true });
var transaction = db.transaction(["customers"], "readwrite");
// transaction is a request; add your onsuccess and onerror handlers
var objectStore = transaction.objectStore("customers");
objectStore.add({name: "Jane", email: "jane@jane.tld", ssn: "444-33-4444"});
// or
objectStore.delete({"444-33-4444"});
// or
var request = objectStore.get({"444-334444"});
// set up your onsuccess and onerror handlers; the result is request.result.{field name}
Still to come - iterating all or some values in a store, upgrading object stores, using indexes, handling different DB versions in separate tabs...
Given that, I recommend letting other people do the hard work for you:
IDBWrapper is one library to try if IndexedDB appears intimidating
Consider starting up a mobile game on the subway.
<html manifest="manifest.cache">
CACHE MANIFEST
CACHE:
index.html
highscores.html
style.css
code.js
NETWORK:
highscores.php
/cgi-bin/*
FALLBACK:
highscores.php highscores.html
applicationCache.swapCache()
function onUpdateReady() {
// Ensure the browser uses the latest version of the code
applicationCache.swapCache();
// Reload the application
location.reload();
}
applicationCache.addEventListener('updateready', onUpdateReady);
if(applicationCache.status === applicationCache.UPDATEREADY) {
onUpdateReady();
}
Example: attempt to fetch dynamic highscores for a game; if that fails, fall back to a static page with default scores.
Store the player's scores locally and update the list accordingly.
navigator.onLine
?
window.ononline/window.onoffline
?
Short answer: attempt a network request.
favicon.ico
)XmlHTTPRequest
s and deal with failures as they occurEither way you need to handle failure of an actual remote request that is supposed to do something.
Bootstrap the detection process by observing the appcache's error event on page load.
window.applicationCache.addEventListener("error", function(e) {
alert("Error fetching manifest: a good chance we are offline");
});
Expect and account for failures.
Consider showing updated data locally.
Buffer updates, push them as a group when network available.
navigator.geolocation.getCurrentPosition/watchPosition
allow retrieving cached data via maxAge
.
Once you obtain a valid position, consider how long an app can be useful while using outdated data.
Put your static resources in the appcache.
Fetch dynamic data when possible, and keep it in offline storage if it will be useful later.
Fall back to most recent static data when dynamic data is impossible.
Store updates until they are transmitted - even between sessions.
Handle failure gracefully!
Josh Matthews - www.joshmatthews.net
/
#