Mobile or not mobile? this is the question …

http://detectmobilebrowsers.com/

JQUERY

/**
 * jQuery.browser.mobile (http://detectmobilebrowser.com/)
 *
 * jQuery.browser.mobile will be true if the browser is a mobile device
 *
 **/
(function(a){(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera);

PHP

<?php
$useragent=$_SERVER['HTTP_USER_AGENT'];
if(preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i',$useragent)||preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i',substr($useragent,0,4)))
header('Location: http://detectmobilebrowser.com/mobile');
?>

http://www.quirksmode.org/js/detect.html

JAVASCRIPT

A useful but often overrated JavaScript function is the browser detect. Sometimes you want to give specific instructions or load a new page in case the viewer uses, for instance, Safari.

If you’re new to JavaScript, don’t use browser detects. You don’t need them. Please read the object detection page first.

Use WhichBrowser

This page used to contain my own browser detect script, but I found that I do not have enough time to keep it up to date. Therefore I removed it.

I advise you to use WhichBrowser. It’s up-to-date, and contains a treasure trove of mobile information.

If you use my old script I advise you to switch to WhichBrowser.

navigator

Below you see the objects contained by the object navigator. These variables can be read out and give information about the browser and computer of your users.

navigator.webkitPersistentStorage = [object DeprecatedStorageQuota]
navigator.webkitTemporaryStorage = [object DeprecatedStorageQuota]
navigator.geolocation = [object Geolocation]
navigator.doNotTrack = null
navigator.onLine = true
navigator.languages = it-IT,it,en-US,en
navigator.language = it
navigator.userAgent = Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36
navigator.product = Gecko
navigator.platform = MacIntel
navigator.appVersion = 5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36
navigator.appName = Netscape
navigator.appCodeName = Mozilla
navigator.hardwareConcurrency = 4
navigator.maxTouchPoints = 0
navigator.vendorSub = 
navigator.vendor = Google Inc.
navigator.productSub = 20030107
navigator.cookieEnabled = true
navigator.mimeTypes = [object MimeTypeArray]
navigator.plugins = [object PluginArray]
navigator.javaEnabled = function javaEnabled() { [native code] }
navigator.getStorageUpdates = function getStorageUpdates() { [native code] }
navigator.vibrate = function vibrate() { [native code] }
navigator.webkitGetGamepads = function webkitGetGamepads() { [native code] }
navigator.getGamepads = function getGamepads() { [native code] }
navigator.webkitGetUserMedia = function webkitGetUserMedia() { [native code] }
navigator.registerProtocolHandler = function registerProtocolHandler() { [native code] }

 

 

 

 

 

 

 


PHP

Mobile Detect

Motto: “Every business should have a mobile detection script to detect mobile readers.”

Mobile_Detect is a lightweight PHP class for detecting mobile devices (including tablets). It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.

We’re commited to make Mobile_Detect the best open-source mobile detection resource and this is why before each release we’re running unit tests, we also research and update the detection rules on daily and weekly basis.

Your website’s content strategy is important! You need a complete toolkit to deliver an experience that is optimizedfast and relevant to your users. Mobile_Detect class is a server-side detection tool that can help you with your RWD strategy, it is not a replacement for CSS3 media queries or other forms of client-side feature detection.

Download and demo

 

Download Docs Examples
Go to releases Become a contributor Code examples
Mobile_Detect.php History :iphone: Live demo!
Composer package

 

Sosteniamo http://www.liberliber.it/

Liber Liber, nota per il progetto Manuzio, biblioteca digitale accessibile gratuitamente, e per l’archivio musicaleLiberMusica, è una o.n.l.u.s. (organizzazione non lucrativa di utilità sociale) che ha come obiettivo la promozione di ogni espressione artistica e intellettuale. In particolare, Liber Liber si propone di favorire l’utilizzazione consapevole delle tecnologie informatiche in campo umanistico e di avvicinare la cultura umanistica e quella scientifica.

 

Liber Liber è stata ufficialmente costituita con atto notarile il 28 novembre 1994, pur operando fin dal 1993. Il suo statuto è on-line.

Grazie alla collaborazione di volontari e sponsor come la E-text, i capolavori della letteratura e le altre opere pubblicate nella nostra mediateca vengono prelevate mensilmente da centinaia di migliaia di utenti.

Come sostenere LIBER LIBER

Carta di credito (server sicuro PayPal)
Bonifico bancario
Bollettino conto corrente postale
Vaglia
Flattr
Onebip

Richiedi gadget
5 per mille

LIBRIVOX.ORG – libertà di ascoltare

Segnalo questo interessante progetto di audiolettura

Browsing Italian

Order by

Release date

Tab Styles Inspiration

Go to CODROPS [source]</a

TabStylesInspiration

View demo Download source

Today we’d like to share a couple of tab styles with you. The collection contains some styles and effects for modern tabs; from a simple box to a SVG shape. Depending on your design, different tab layouts and looks can spice up your sections; think outside of the box (literally) and you’ll see how interesting the usually boring tabs can become.

For the demo we’ve used a flexbox layout so make sure you view it with a modern browser.

The icons in most of the tabs are from the fantastic Elegant Themes Line Icon Set and we’ve used the Icomoon app to create our custom icon font.

For the tab functionality we’ve used the Blueprint Responsive Full Width Tabs and adjusted it for our needs.

The main common tab style for all tabs can be found in tabs.css and all individual styles are in tabstyles.css

Take a look at some of the examples:

Tab-Style-Inspiration04

Tab-Style-Inspiration03

Tab-Style-Inspiration02

Tab-Style-Inspiration01

There are a couple of example media queries and fallbacks that can be customized. We’ve opted for showing icons only on smaller screens (see the Blueprint) or a horizontal stack where it makes sense.

We hope you enjoy these styles and get inspired :)

Building A Simple Cross-Browser Offline To-Do List With IndexedDB And WebSQL

Go to Source

Making an application work offline can be a daunting task. In this article, Matthew Andrews, a lead developer behind FT Labs, shares a few insights he had learned along the way while building the FT application. Matthew will also be running a “Making It Work Offline” workshop1 at our upcoming Smashing Conference in Freiburg in mid-September 2014. — Ed.

We’re going to make a simple offline-first to-do application2 with HTML5 technology. Here is what the app will do:

  • store data offline and load without an Internet connection;
  • allow the user to add and delete items in the to-do list;
  • store all data locally, with no back end;
  • run on the first- and second-most recent versions of all major desktop and mobile browsers.

The complete project is ready for forking on GitHub3.

Which Technologies To Use

In an ideal world, we’d use just one client database technology. Unfortunately, we’ll have to use two:

Veterans of the offline-first world might now be thinking, “But we could just use localStorage6, which has the benefits of a much simpler API, and we wouldn’t need to worry about the complexity of using both IndexedDB and WebSQL.” While that is technically true, localStorage has number of problems7, the most important of which is that the amount of storage space available with it is significantly less than IndexedDB and WebSQL.

Luckily, while we’ll need to use both, we’ll only need to think about IndexedDB. To support WebSQL, we’ll use an IndexedDB polyfill8. This will keep our code clean and easy to maintain, and once all browsers that we care about support IndexedDB natively, we can simply delete the polyfill.

Note: If you’re starting a new project and are deciding whether to use IndexedDB or WebSQL, I strongly advocate using IndexedDB and the polyfill. In my opinion, there is no reason to write any new code that integrates with WebSQL directly.

I’ll go through all of the steps using Google Chrome (and its developer tools), but there’s no reason why you couldn’t develop this application using any other modern browser.

1. Scaffolding The Application And Opening A Database

We will create the following files in a single directory:

  • /index.html
  • /application.js
  • /indexeddb.shim.min.js
  • /styles.css
  • /offline.appcache

/index.html

<!DOCTYPE html>
<html>
  <head>
    <link rel='stylesheet' href='./styles.css' type='text/css' media='all' />
  </head>
  <body>
    <h1>Example: Todo</h1>
    <form>
      <input placeholder="Type something" />
    </form>
    <ul>
    </ul>
    <script src="./indexeddb.shim.min.js"></script>
    <script src="./application.js"></script>
  </body>
</html>

Nothing surprising here: just a standard HTML web page, with an input field to add to-do items, and an empty unordered list that will be filled with those items.

/indexeddb.shim.min.js

Download the contents of the minified IndexedDB polyfill9, and put it in this file.

/styles.css

body {
  margin: 0;
  padding: 0;
  font-family: helvetica, sans-serif;
}

* {
  box-sizing: border-box;
}

h1 {
  padding: 18px 20px;
  margin: 0;
  font-size: 44px;
  border-bottom: solid 1px #DDD;
  line-height: 1em;
}

form {
  padding: 20px;
  border-bottom: solid 1px #DDD;
}

input {
  width: 100%;
  padding: 6px;
  font-size: 1.4em;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

li {
  padding: 20px;
  border-bottom: solid 1px #DDD;
  cursor: pointer;
}

Again, this should be quite familiar: just some simple styles to make the to-do list look tidy. You may choose not to have any styles at all or create your own.

/application.js

(function() {

  // 'global' variable to store reference to the database
  var db;

  databaseOpen(function() {
    alert("The database has been opened");
  });

  function databaseOpen(callback) {
    // Open a database, specify the name and version
    var version = 1;
    var request = indexedDB.open('todos', version);

    request.onsuccess = function(e) {
      db = e.target.result;
      callback();
    };
    request.onerror = databaseError;
  }

  function databaseError(e) {
    console.error('An IndexedDB error has occurred', e);
  }

}());

All this code does is create a database with indexedDB.open and then show the user an old-fashioned alert if it is successful. Every IndexedDB database needs a name (in this case, todos) and a version number (which I’ve set to 1).

To check that it’s working, open the application in the browser, open up “Developer Tools” and click on the “Resources” tab.

In the Resources panel, you can check whether it's working.
In the “Resources” panel, you can check whether it’s working.

By clicking on the triangle next to “IndexedDB,” you should see that a database named todos has been created.

2. Creating The Object Store

Like many database formats that you might be familiar with, you can create many tables in a single IndexedDB database. These tables are called “objectStores.” In this step, we’ll create an object store named todo. To do this, we simply add an event listener on the database’s upgradeneeded event.

The data format that we will store to-do items in will be JavaScript objects, with two properties:

  • timeStamp
    This timestamp will also act as our key.
  • text
    This is the text that the user has entered.

For example:

{ timeStamp: 1407594483201, text: 'Wash the dishes' }

Now, /application.js looks like this (the new code starts at request.onupgradeneeded):

(function() {

  // 'global' variable to store reference to the database
  var db;

  databaseOpen(function() {
    alert("The database has been opened");
  });

  function databaseOpen(callback) {
    // Open a database, specify the name and version
    var version = 1;
    var request = indexedDB.open('todos', version);

    // Run migrations if necessary
    request.onupgradeneeded = function(e) {
      db = e.target.result;
      e.target.transaction.onerror = databaseError;
      db.createObjectStore('todo', { keyPath: 'timeStamp' });
    };

    request.onsuccess = function(e) {
      db = e.target.result;
      callback();
    };
    request.onerror = databaseError;
  }

  function databaseError(e) {
    console.error('An IndexedDB error has occurred', e);
  }

}());

This will create an object store keyed by timeStamp and named todo.

Or will it?

Having updated application.js, if you open the web app again, not a lot happens. The code in onupgradeneeded never runs; try adding a console.log in the onupgradeneeded callback to be sure. The problem is that we haven’t incremented the version number, so the browser doesn’t know that it needs to run the upgrade callback.

How to Solve This?

Whenever you add or remove object stores, you will need to increment the version number. Otherwise, the structure of the data will be different from what your code expects, and you risk breaking the application.

Because this application doesn’t have any real users yet, we can fix this another way: by deleting the database. Copy this line of code into the “Console,” and then refresh the page:

indexedDB.deleteDatabase('todos');

After refreshing, the “Resources” pane of “Developer Tools” should have changed and should now show the object store that we added:

The Resources panel should now show the object store that was added.
The “Resources” panel should now show the object store that was added.

3. Adding Items

The next step is to enable the user to add items.

/application.js

Note that I’ve omitted the database’s opening code, indicated by ellipses (…) below:

(function() {

  // Some global variables (database, references to key UI elements)
  var db, input;

  databaseOpen(function() {
    input = document.querySelector('input');
    document.body.addEventListener('submit', onSubmit);
  });

  function onSubmit(e) {
    e.preventDefault();
    databaseTodosAdd(input.value, function() {
      input.value = '';
    });
  }

[…]

  function databaseTodosAdd(text, callback) {
    var transaction = db.transaction(['todo'], 'readwrite');
    var store = transaction.objectStore('todo');
    var request = store.put({
      text: text,
      timeStamp: Date.now()
    });

    transaction.oncomplete = function(e) {
      callback();
    };
    request.onerror = databaseError;
  }

}());

We’ve added two bits of code here:

  • The event listener responds to every submit event, prevents that event’s default action (which would otherwise refresh the page), calls databaseTodosAdd with the value of the input element, and (if the item is successfully added) sets the value of the input element to be empty.
  • A function named databaseTodosAdd stores the to-do item in the local database, along with a timestamp, and then runs a callback.

To test that this works, open up the web app again. Type some words into the input element and press “Enter.” Repeat this a few times, and then open up “Developer Tools” to the “Resources” tab again. You should see the items that you typed now appear in the todo object store.

03-step3-dev-tools-opt-50010
After adding a few items, they should appear in the todo object store. (View large version11)

4. Retrieving Items

Now that we’ve stored some data, the next step is to work out how to retrieve it.

/application.js

Again, the ellipses indicate code that we have already implemented in steps 1, 2 and 3.

(function() {

  // Some global variables (database, references to key UI elements)
  var db, input;

  databaseOpen(function() {
    input = document.querySelector('input');
    document.body.addEventListener('submit', onSubmit);
    databaseTodosGet(function(todos) {
      console.log(todos);
    });
  });

[…]

  function databaseTodosGet(callback) {
    var transaction = db.transaction(['todo'], 'readonly');
    var store = transaction.objectStore('todo');

    // Get everything in the store
    var keyRange = IDBKeyRange.lowerBound(0);
    var cursorRequest = store.openCursor(keyRange);

    // This fires once per row in the store. So, for simplicity,
    // collect the data in an array (data), and pass it in the
    // callback in one go.
    var data = [];
    cursorRequest.onsuccess = function(e) {
      var result = e.target.result;

      // If there's data, add it to array
      if (result) {
        data.push(result.value);
        result.continue();

      // Reach the end of the data
      } else {
        callback(data);
      }
    };
  }

}());

After the database has been initialized, this will retrieve all of the to-do items and output them to the “Developer Tools” console.

Notice how the onsuccess callback is called after each item is retrieved from the object store. To keep things simple, we put each result into an array named data, and when we run out of results (which happens when we’ve retrieved all of the items), we call the callback with that array. This approach is simple, but other approaches might be more efficient.

If you reopen the application again, the “Developer Tools” console should look a bit like this:

The console after reopening the application
The console after reopening the application

5. Displaying Items

The next step after retrieving the items is to display them.

/application.js

(function() {

  // Some global variables (database, references to key UI elements)
  var db, input, ul;

  databaseOpen(function() {
    input = document.querySelector('input');
    ul = document.querySelector('ul');
    document.body.addEventListener('submit', onSubmit);
    databaseTodosGet(renderAllTodos);
  });

  function renderAllTodos(todos) {
    var html = '';
    todos.forEach(function(todo) {
      html += todoToHtml(todo);
    });
    ul.innerHTML = html;
  }

  function todoToHtml(todo) {
    return '
  • '+todo.text+'
  • '; } […]

    All we’ve added are a couple of very simple functions that render the to-do items:

    • todoToHtml
      This takes a todos object (i.e. the simple JavaScript object that we defined earlier).
    • renderAllTodos
      This takes an array of todos objects, converts them to an HTML string and sets the unordered list’s innerHTML to it.

    Finally, we’re at a point where we can actually see what our application is doing without having to look in “Developer Tools”! Open up the app again, and you should see something like this:

    Your application in the front-end view12
    Your application in the front-end view (View large version13)

    But we’re not done yet. Because the application only displays items when it launches, if we add any new ones, they won’t appear unless we refresh the page.

    6. Displaying New Items

    We can fix this with a single line of code.

    /application.js

    The new code is just the line databaseTodosGet(renderAllTodos);.

    […]
    
    function onSubmit(e) {
      e.preventDefault();
      databaseTodosAdd(input.value, function() {
        // After new items have been added, re-render all items
        databaseTodosGet(renderAllTodos);
        input.value = '';
      });
    }
    
    […]
    

    Although this is very simple, it’s not very efficient. Every time we add an item, the code will retrieve all items from the database again and render them on screen.

    7. Deleting Items

    To keep things as simple as possible, we will let users delete items by clicking on them. (For a real application, we would probably want a dedicated “Delete” button or show a dialog so that an item doesn’t get deleted accidentally, but this will be fine for our little prototype.)

    To achieve this, we will be a little hacky and give each item an ID set to its timeStamp. This will enable the click event listener, which we will add to the document’s body, to detect when the user clicks on an item (as opposed to anywhere else on the page).

    /application.js

    (function() {
    
      // Some global variables (database, references to key UI elements)
      var db, input, ul;
    
      databaseOpen(function() {
        input = document.querySelector('input');
        ul = document.querySelector('ul');
        document.body.addEventListener('submit', onSubmit);
        document.body.addEventListener('click', onClick);
        databaseTodosGet(renderAllTodos);
      });
    
      function onClick(e) {
    
        // We'll assume that any element with an ID
        // attribute is a to-do item. Don't try this at home!
        if (e.target.hasAttribute('id')) {
    
          // Because the ID is stored in the DOM, it becomes
          // a string. So, we need to make it an integer again.
          databaseTodosDelete(parseInt(e.target.getAttribute('id'), 10), function() {
    
            // Refresh the to-do list
            databaseTodosGet(renderAllTodos);
          });
        }
      }
    
    […]
    
      function todoToHtml(todo) {
        return '<li id="'+todo.timeStamp+'">'+todo.text+'</li>';
      }
    
    […]
    
      function databaseTodosDelete(id, callback) {
        var transaction = db.transaction(['todo'], 'readwrite');
        var store = transaction.objectStore('todo');
        var request = store.delete(id);
        transaction.oncomplete = function(e) {
          callback();
        };
        request.onerror = databaseError;
      }
    
    }());
    

    We’ve made the following enhancements:

    • We’ve added a new event handler (onClick) that listens to click events and checks whether the target element has an ID attribute. If it has one, then it converts that back into an integer with parseInt, calls databaseTodosDelete with that value and, if the item is successfully deleted, re-renders the to-do list following the same approach that we took in step 6.
    • We’ve enhanced the todoToHtml function so that every to-do item is outputted with an ID attribute, set to its timeStamp.
    • We’ve added a new function, databaseTodosDelete, which takes that timeStamp and a callback, deletes the item and then runs the callback.

    Our to-do app is basically feature-complete. We can add and delete items, and it works in any browser that supports WebSQL or IndexedDB (although it could be a lot more efficient).

    Almost There

    Have we actually built an offline-first to-do app? Almost, but not quite. While we can now store all data offline, if you switch off your device’s Internet connection and try loading the application, it won’t open. To fix this, we need to use the HTML5 Application Cache14.

    Warning

    • While HTML5 Application Cache works reasonably well for a simple single-page application like this, it doesn’t always. Thoroughly research how it works15 before considering whether to apply it to your website.
    • Service Worker16 might soon replace HTML5 Application Cache, although it is not currently usable in any browser, and neither Apple nor Microsoft have publicly committed to supporting it.

    8. Truly Offline

    To enable the application cache, we’ll add a manifest attribute to the html element of the web page.

    /index.html

    <!DOCTYPE html>
    <html manifest="./offline.appcache">
    […]
    

    Then, we’ll create a manifest file, which is a simple text file in which we crudely specify the files to make available offline and how we want the cache to behave.

    /offline.appcache

    CACHE MANIFEST
    ./styles.css
    ./indexeddb.shim.min.js
    ./application.js
    
    NETWORK:
    *
    

    The section that begins CACHE MANIFEST tells the browser the following:

    • When the application is first accessed, download each of those files and store them in the application cache.
    • Any time any of those files are needed from then on, load the cached versions of the files, rather than redownload them from the Internet.

    The section that begins NETWORK tells the browser that all other files must be downloaded fresh from the Internet every time they are needed.

    Success!

    We’ve created a quick and simple to-do app17 that works offline and that runs in all major modern browsers, thanks to both IndexedDB and WebSQL (via a polyfill).

    Resources

    (al, ml, il)

    Footnotes

    1. 1 http://smashingconf.com/workshops/matthew-andrews
    2. 2 https://matthew-andrews.github.io/offline-todo/
    3. 3 https://github.com/matthew-andrews/offline-todo
    4. 4 http://caniuse.com/indexeddb
    5. 5 http://caniuse.com/sql-storage
    6. 6 http://caniuse.com/namevalue-storage
    7. 7 https://hacks.mozilla.org/2012/03/there-is-no-simple-solution-for-local-storage/
    8. 8 https://github.com/axemclion/IndexedDBShim
    9. 9 https://raw.githubusercontent.com/matthew-andrews/offline-todo/gh-pages/indexeddb.shim.min.js
    10. 10 http://www.smashingmagazine.com/wp-content/uploads/2014/08/03-step3-dev-tools-opt.jpg
    11. 11 http://www.smashingmagazine.com/wp-content/uploads/2014/08/03-step3-dev-tools-opt.jpg
    12. 12 http://www.smashingmagazine.com/wp-content/uploads/2014/08/05-step5-app-opt.jpg
    13. 13 http://www.smashingmagazine.com/wp-content/uploads/2014/08/05-step5-app-opt.jpg
    14. 14 https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache
    15. 15 http://alistapart.com/article/application-cache-is-a-douchebag
    16. 16 http://www.serviceworker.org/
    17. 17 https://matthew-andrews.github.io/offline-todo/
    18. 18 http://www.html5rocks.com/en/tutorials/indexeddb/todo/
    19. 19 http://nparashuram.com/IndexedDBShim/
    20. 20 http://alistapart.com/article/application-cache-is-a-douchebag
    21. 21 https://jakearchibald.github.io/isserviceworkerready/

    The post Building A Simple Cross-Browser Offline To-Do List With IndexedDB And WebSQL appeared first on Smashing Magazine.

    After the crowdfund, websites of successful Kickstarter campaigns

    Go to Source

    kickstarter campaign websitesKickstarter has become a huge influencer in the startup space, as well as in the entertainment and arts industries among independent creators. Everything from movie sequels for popular TV shows to potato salad have been funded on the site, along with making a lot of dreams come true for creators and entrepreneurs.

    But after most Kickstarter campaigns are completed, companies and projects have to continue to exist on the Web. That means websites, in most cases. Studying how different projects and companies have handled their post-Kickstarter websites provides some fascinating insight into what happens after the fundraising stops, as well as how Kickstarter is perceived in various industries.

    Film & Video

    The film and video category is one of the largest on Kickstarter, with numerous campaigns earning over a million dollars (including one that raised over five million).

    Wish I Was Here

    Kickstarter Page | Website

    The website for Wish I Was Here is a fantastic example of what a film website should be. It makes it easy to find the pertinent information about the film while keeping things simple and visually striking. They don’t mention the Kickstarter campaign anywhere on the home page.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Kung Fury

    Kickstarter Page | Website

    The Kung Fury website is simple and to the point. The trailer is featured prominently, as is the Kickstarter fundraising information.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Bridegroom

    Kickstarter Page | Website

    The Bridegroom website is simple, putting the emphasis on the awards the film has won, with easy-to-find links to more information. It doesn’t mention the Kickstarter campaign anywhere on the home page.

    After the crowdfund, websites of successful Kickstarter campaigns

    Enemy of Man

    Kickstarter Page | Website

    The Enemy of Man website resembles a big budget Hollywood studio film site more than any of the others here, which makes sense considering some of the stars of the film (including Sean Bean and Rupert Grint). The Kickstarter campaign gets a prominent link in the top navigation, right alongside links to the trailer, synopsis, and cast.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    The Outs

    Kickstarter Page | Website

    Web series The Outs has a simple but visually striking website design, featuring stills from the show itself in a background slideshow. Links to info about the show (including a watch link, about, soundtrack, and more) are easy to find along the bottom. There’s no mention of either Kickstarter campaign on the home page.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Conclusion

    Mentions of Kickstarter are pretty evenly split among film and video projects, with some not mentioning their origins and others displaying it prominently. Only one site, though, opted to include more than a link to their Kickstarter campaign (as opposed to information about the amount raised, etc).

     

    Design

    The design category covers a ton of different projects, but seems to heavily feature product designs. It’s also the only Kickstarter category that has had a project raise over $10 million.

    Lomography Petzval Art Lens

    Kickstarter Page | Website

    The Lomography Petzval Art Lens microsite has a simple design with a slideshow in the header, with links to all the information you might want about the product. A link to the Kickstarter campaign is included in the main navigation.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Kano

    Kickstarter Page | Website

    The Kano website uses parallax scroll animations that help to explain what the product is and what it does. The only Kickstarter link on the home page is included among the other social links in the footer. Instead, the site focuses on media coverage they’ve received and making the product come alive.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Lomo’Instant

    Kickstarter Page | Website

    The Lomo’Instant microsite is minimal with images of the products front and center. It’s a single-page site, with camera specs, media coverage, a photo gallery and more. It also includes a prominent Kickstarter badge right at the top of the home page.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Brydge Keyboards

    Kickstarter Page | Website

    The Brydge website focuses on a product video, with the different product options featured directly below it. There’s no link to or mention of the Kickstarter campaign on the home page, a departure from most other design campaigns.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Vanhawks Valour

    Kickstarter Page | Website

    The Vanhawks Valour bike website has a clean and simple design with large images of the bike on the home page. Simple top navigation makes it easy to find the information you might be looking for. A Kickstarter badge is located prominently right next to the pre-order button.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Conclusion

    Most of the products in the design category prominently feature links to their Kickstarter roots. This makes sense, as uber-successful Kickstarter-funded projects tend to get a lot of press and a lot of attention from the design and tech communities.

     

    Games

    The games category covers both digital games and physical games, so it has tons of diversity, with quite a few projects raising well over a million dollars.

    Kingdom Come RPG

    Kickstarter Page | Website

    The Kingdom Come RPG website has an animated header that draws in visitors. It also prominently features a link for visitors to contribute, though it’s directly on the website rather than via Kickstarter. In fact, there’s no Kickstarter link at all on the home page.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Shadowrun Returns

    Kickstarter Page | Website

    The Shadowrun Returns website is primarily a blog, deviating from the norm of other sites in this category, with links for where to purchase the game in the sidebar. There’s no prominent mention of the Kickstarter campaign.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Oculus Rift

    Kickstarter Page | Website

    The Oculus Rift website packs a lot of information into the home page, with top navigation, product info, news, and more. While this was a very prominent and successful Kickstarter campaign, the only Kickstarter mention is in the site’s footer.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Camelot Unchained

    Kickstarter Page | Website

    The Camelot Unchained website is another site that continues to crowdfund after their Kickstarter campaign has ended. Pledges are taken directly on the website, with no intermediary. The only prominent Kickstarter mention is in their fundraising tally chart, where they display the Kickstarter total alongside the PayPal total.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Star Citizen

    Kickstarter Page | Website

    The Star Citizen game website offers up tons of information about the game, plus links to pledge and reserve your ship in the game. There’s a lot of information packed into the home page, which can make it difficult to find the info you want. There’s no mention of Kickstarter on the home page.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Conclusion

    One common thread among a number of successfully-funded games is the fact that they continue fundraising after their Kickstarter campaigns have ended, often raising a significant amount of additional funds. Most of the game sites don’t mention Kickstarter prominently, regardless of whether they continue to raise funds or not.

     

    Technology

    The technology category has been host to some very successful projects over the years, with some of the biggest successes focusing around 3D printing and music-related tech. And of course there was the campaign to resurrect Reading Rainbow.

    Airdog

    Kickstarter Page | Website

    The Airdog website is fun and creative, matching the design of the product itself. Product pre-orders are listed right at the top of the home page, along with media coverage the product has received. There’s a fairly prominent Kickstarter badge, along with information on how much money they raised on the site and how many backers they had. It’s integrated in a very smooth and visually pleasing way.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Lifx

    Kickstarter Page | Website

    The Lifx lightbulb website is simple, yet stunning. It focuses on the product, with enough information to answer likely visitor questions without overwhelming the visitor with too much content. The bottom of the home page includes links to the Kickstarter video and to prominent media coverage, along with a bit of product backstory.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Hexo+

    Kickstarter Page | Website

    The Hexo+, which is a similar product to the Airdog, takes a totally different approach to their website, with a modern, minimalist design. The site is simple, with plenty of well-constructed information about the product. The footer holds a prominent Kickstarter badge, but otherwise the campaign isn’t really mentioned.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Sense

    Kickstarter Page | Website

    The Sense website offers up clear information about the product, with strong visuals and just the right amount of content. Media coverage is featured prominently, complete with quotes from the various articles. There’s a prominent Kickstarter link in the header, as well as a full-width banner just above the footer. It’s one of the more prominent Kickstarter inclusions in this industry.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Earin

    Kickstarter Page | Website

    The Earin website includes a prominent content slider (complete with video) that takes up most of the visible portion of the home page when it loads. Immediately under the slider and a bit of intro text is a big Kickstarter link and logo. Below that is more information about the product.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Conclusion

    Tech campaigns on Kickstarter tend to include Kickstarter links and badges, but they vary greatly in prominence. Some companies seem to want to brag about their Kickstarter success, while others treat it as just another facet of their business.

     

    Fashion

    The fashion category is varied, in that it includes both products from individual companies and entire startups. While the fashion category doesn’t tend to raise as much dollar-wise (there’s only one campaign that’s raised over a million dollars so far), a lot of very cool products have resulted from Kickstarter campaigns.

    The Versalette

    Kickstarter Page | Website

    The page for The Versalette makes little mention of the Kickstarter campaign, except for a text mention at the very bottom referring to it, and instead focuses primarily on the product. Since it’s part of a larger website selling other products, the general design follows suit. But the custom page that isn’t simply a sales page and instead delves into the background of the product and what makes it unique is a nice touch.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Parke

    Kickstarter Page | Website

    The Parke New York website is simple and minimalist, with the focus on the products. They include general information about the jeans, links to the men’s and women’s collections, and media coverage. There’s no mention of the Kickstarter campaign, though, nor any social media links.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Boston Boot Co.

    Kickstarter Page | Website

    It appears that Boston Boot Co. was started via Kickstarter funding, but you’d never know that from their website. Instead, the focus is placed squarely on the brand and their products. The content slider on the home page grabs the visitor’s attention immediately, while links to the collection and more about what the company does are prominent.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Barbell Apparel

    Kickstarter Page | Website

    Barbell Apparel’s website is another one that makes no prominent mention of Kickstarter on the home page, though they do carry over the term “Backer” to anyone who places a pre-order on the site. The main focus of the home page is a product video, along with links to the collections. There’s also a lot of prominence placed on the fact that products are manufactured in American factories.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Sword & Plough

    Kickstarter Page | Website

    The Sword & Plough site is simple, with a definite hipster aesthetic. The site showcases the products and the story behind the manufacturing (they work with veterans to repurpose military surplus fabric into bags), but the make no mention of their Kickstarter origins.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Conclusion

    While many other successfully funded products in other industries mention or even heavily feature their Kickstarter origins, the fashion industry seems to be the outlier in this. Very few sites draw attention to their Kickstarter campaigns after the fact, though the reasons for this are unclear and likely vary from company to company.

     

    Everything else

    The above categories are likely to be of particular interest to designers, but there are plenty of other categories funded via Kickstarter. Here are some successful campaigns from those, and how their websites shape up in comparison.

    Masters of Anatomy

    Kickstarter Page | Website

    The Masters of Anatomy site draws attention primarily to two things, beyond the product itself: the artists who are involved, and their Kickstarter campaign, which raised over half a million dollars.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Hello Ruby

    Kickstarter Page | Website

    Hello Ruby’s website is whimsical and perfectly suited to a children’s book, particularly one aimed at kids whose parents are highly tech-savvy. The Kickstarter video is included right on the home page, which may have a lot to do with the tech-related origins of the product (since Kickstarter tends to have more sway in that sector).

    After the crowdfund, websites of successful Kickstarter campaigns

     

    The Bear

    Kickstarter Page | Website

    The Bear is an art book that includes artwork that paints the bond between a first-time parent and child. The site itself is fitting of the product. The only tie-in to the Kickstarter campaign is the list of backers who helped fund the book.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Windowfarms

    Kickstarter Page | Website

    The Windowfarms website is simple and minimalist, with simple ordering options and links to media coverage. There’s no mention of the Kickstarter campaign anywhere on the home page.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    PicoBrew

    Kickstarter Page | Website

    The PicoBrew site’s main content slider beautifully showcases the product. There are social media links for Instagram, Twitter, and Facebook, and links to media coverage of the product. But again, no Kickstarter link.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Civil Eats

    Kickstarter Page | Website

    The Civil Eats website is a daily news website discussing the American food system. It has a clean design, with no mention of Kickstarter at all.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Nomiku

    Kickstarter Page | Website

    The Nomiku website is fun and colorful, with a content slider that includes product information and media coverage all rolled into one. Kickstarter isn’t mentioned, there or anywhere else on the page.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    KitRex

    Kickstarter Page | Website

    KitRex, the origami T-rex, prominently features their Kickstarter campaign, both in the home page body and in the header.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Ava’s Demon

    Kickstarter Page | Website

    The Ava’s Demon website has a bold, unique design. While the home page has a lot of information covered, it doesn’t featured Kickstarter prominently at all, though it is mentioned in the text.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Urban Air

    Kickstarter Page | Website

    The home page of the Urban Air art project features a full-size image of the installations themselves. The project transforms billboards into living suspended bamboo gardens, and their LA project was funded via Kickstarter. You’d never know it from the website though.

    After the crowdfund, websites of successful Kickstarter campaigns

     

    Conclusion

    Kickstarter has been a part of the successful fundraising of thousands of projects across more than a dozen industries. But how the businesses who have been made possible because of Kickstarter actually handle their association with the platform after the fact varies greatly, both between industries and within some industries themselves. Studying how others have handled these kinds of site designs is a valuable lesson in not only how to handle your own Kickstarter website designs, but also offers insight into how Kickstarter may be perceived in various industries.

    PITCHSTOCK: Marketing Diagram & Sitemap Kit Bundle – only $12!
    After the crowdfund, websites of successful Kickstarter campaigns

    Source