Click here to Skip to main content
11,701,953 members (50,851 online)
Click here to Skip to main content

Tagged as

Beginner's Guide to HTML5 & CSS3 - Web Storage Wizardry

, 4 May 2014 CPOL 7.9K 306 19
Rate this:
Please Sign up or sign in to vote.
Building storage area in browsers.

Introduction

The World Wide Web (WWW) is originally stateless. HTTP (HyperText Transfer Protocol) - a set of rules that governs communications on the WWW, provides no means for maintaining states. Using HTTP alone, every request for a web page is a new and isolated one. In other words, you are anonymous or faceless to the website as it does not recognize you or remember your previous visits. This stateless WWW can be liken to your affair with the vending machines you frequent to buy your favorite beverages and snacks. These machines do not recognize you or remember your previous purchases. This type of model is fine if each transaction is independent and can be completed in a single cycle of request (press the product button) and response (out come the product).

The stateless model of WWW cannot meet the sophisticated demands of today's web applications. A typical e-commence transaction session on the web, for example, will consists of a connected series of consecutive and iterative cycle of requests and responses - From browsing and searching items, adding items to cart, displaying cart content, changing cart items (iterative), changing item quantities (iterative), to checking out all within a single session. For this to happen, the e-commerce website must recognize you and remember your preceding activities with the website in order for it to correctly process your subsequent requests such as displaying cart content, changing cart items etc. In order words, today's web applications must employ some mechanism to maintain states in order to function properly.

To mend this shortfall, cookies were invented.

Cookies No Enough

Cookies, not your favorite edible snacks, were invented in the early years to meet the demands of maintaining states by websites. A cookie is a little text file of no more than 4KB that stores a user's information pertaining to a particular website. When a user visits a website with a cookie function for the first time, a cookie is created and sent from the web server to the browser and stored with the browser in the user's computer. This cookie will accompanies subsequent visits (requests) to the same website using the same browser and from the same computer. In this way, the website will be able to recognize you (or rather the browser and the computer) and any information on your preceding visits that were captured in the cookie.

Cookies have its intrinsic limitations since day one. These have been exacerbated by the ever-increasing sophistication of modern web applications.

  • Limited capacity of 4KB is hardly enough and useful.
  • Performance adversity as cookies have to accompany each request to be server.
  • Security vulnerability such as cross site scripting attack.

Another alternative to maintaining states is through the use of session variables which are created and stored temporarily on the web server. As its name suggests, a session variable only survives for a single session. To keep the value of a session variable beyond a single session, it has to be saved to some persistence storage such as a database or a flat file on the server side. This poses resource overhead and increased complexity in implementation.

Is there a better alternative?

HTML5 Web Storage

Yes, the answer is HTML5 Web Storage!

Started out as part of the HTML5 specification proper and later split out into its own specification, HTML5 Web Storage was designed with the vision for a better mechanism to store web data on the client-side. It is implemented as a client-side database provided by a web browser that allows web pages to store data in the form of key-value pairs. It has the following characteristics:

  • Stores up to 5MB of data per origin (website / domain).
  • Has properties and methods that you can access using JavaScript for manipulating data in the web storage.
  • Like cookies, you can choose to make the data stays (persists) even after you navigate away from the website, close the browser tab, exit the browser, or shut down your computer.
  • Unlike cookies, which are created by server-side scripting, web storage is created by client-side scripting like JavaScript.
  • Unlike cookies, the data in the web storage does not automatically accompany every HTTP request to the server.
  • Is implemented and supported natively in major web browsers like Chrome, Opera, Firefox, Safari and IE8+. In other words, no 3rd-party plugins are needed.

Web Storage offers 2 different storage areas - Session Storage and Local Storage - which differ in scope , lifespan, and used in different situations.

Session Storage

Session Storage, as the name suggests, stores data as strings (texts) pertaining to an origin* and lasts only for current session. The data is deleted when the browser window is close. Session Storage is designed for situations where a user carries out multiple transactions in different browser windows concurrently using the same website. Each transaction in each browser windows will get its own copy of session storage which is different from the session storage used by another transaction in another browser windows. When the user closes a browser window, the session storage data that belongs to that window will ease to exist. In this way, the transaction data would not "leak" from one browser window to the others. Session storage is the answer to the following weakness of cookies as stated in the HTML5 Web Storage specification:

Quote:
if a user buying plane tickets in two different windows, using the same site. If the site used cookies to keep track of which ticket the user was buying, then as the user clicked from page to page in both windows, the ticket currently being purchased would "leak" from one window to the other, potentially causing the user to buy two tickets for the same flight without really noticing.

Session storage must be used for web activities that deal with confidential and sensitive information, such as credit card numbers, social security numbers, and login credentials. This information are easy preys for DNS spoofing** attacks and should not be stored beyond a single session.

*Origin is the combination of protocol, hostname, and port number. For example, "http://www.example.com/dir1/index.html" and "http://www.example.com/dir2/index.html" are of the same origin, while "http://example.com/dir1/index.html", "https://www.example.com/dir1/index.html" and "http://www.example.com/dir2/index.html:8080" are not.

**DNS spoofing is a computer hacking attack, in which malicious data is injected into a Domain Name System (DNS), a directory for mapping domain names to real IP addresses, fooling the DNS into returning an incorrect IP address, the result of which causes all traffic bound for a domain being diverted to a phoney doman which is often the attacker's computer.

Local Storage

Local Storage, on the other hand, stores data as strings (texts) pertaining to an origin and lasts forever (unless you delete it explicitly). The data will stay (persist) even when the browser window is close and be available on subsequent visits to the same origin using the same browser window. Local Storage is designed for storing data that spans multiple browser windows and lasts beyond the current session. A simple use case would be to store the number of visits a person has made to some web pages.

Unlike their desktop counterparts, web applications have always been lacking in their ability to work offline. Not anymore, the advent of HTML5 Local storage has made its possible now. Imagine while you are filling out a multi-page web form, composing a lengthy CodeProject article when deadline is imminent, suddenly a network outage occurs disrupting all network connections. You would lose all the data that you have painstakingly created. With local storage, you can continue to work offline while the web application saves your work to the local storage intermittently using some client-side scripting like JavaScript.

A websites can allow users to customize the theme and layout of the web pages and store these settings in the local storage. In this way, users can get their own personlized web pages on subsequent visit. We will see an example later.

By storing gaming status in the local storage, gamers can continue from where they left off by retrieving their last game status from the local storage.

Getting Your Hands Dirty

Sound great! With HTML5 Web Storage, users can now store and manipulate web data just like any other files in their computer. Naturally, this question arises - how to make it happen? Specifically, how to build one of these web storage, how to save, retrieve, update, and remove data from it? The answer lies with your hands. What better way to learn than to make them happen by getting your hands dirty.

Let's start with the session storage first. You will build a simple article subscription web application that will allow a user to add and modify the number of subscription in a single session using Session Storage.

Building Session Storage

Type the following code on the upper part of Figure 1 using a text editor, save it as "sessionstorage.html" inside a folder called "html5webstorage", and launch it on a browser. You should see a web page as shown on the lower part of Figure 1.

Figure 1: sessionstorage.html Shaping up

From here on, you will write JavaScript code for getting the session storage to work. HTML5 Web Storage provides a sessionStorage object for working with session storage. You will learn to use the various methods and properties of this sessionStorage object in your subsequent code.

Retrieving

Add the highlighted code in Figure 2 between the <script> and </script> tags of sessionstorage.html file.

Figure 2: init() Function

You have just added an init() function to sessionstorage.html file. This init() function will be called when the web page has finished loading through the onload event in the <body> tag as shown below:

<body onload="init()">

The init() function essentially does the following tasks:

  • Check the existence of session storage for the current session by calling the length property of the sessionStorage object to find out the number of key-value pairs exist in the storage.
    if (sessionStorage.length != 0) { 
        // sessionStorage exists, retrieve data from storage
        
    } else { 
        // sessionStorage does not exist, set default value
    }
  • If it exists, retrieve one of the previously stored item called "noOfArticleSubscribed" from the Session Storage by calling the getItem() method of the sessionStorage object and passing it the key name of "noOfArticleSubscribed" as parameter. The retrieved value is then assigned to the HTML element identified by the id of "noOfArticleSubscribed". Do not confuse the 2 "noOfArticleSubscribed"''s, one is the key name for a storage item n the session storage, the other the id of an HTML element. You can give them different values if you wish.
    document.getElementById("noOfArticleSubscribed").value = sessionStorage.getItem("noOfArticleSubscribed");
  • That is all that you need to retrieve a stored item, in fact, any stored items from the session storage. But wait a second, what is this:
    if (typeof(Storage)!=="undefined")
    I am glad that you asked. This statement will check whether your browser supports HTML5 Web Storage or not. It should be used to wrap any code that accesses Web Storage.

Saving / Updating

Next, add the highlighted code in Figure 3 after the init() function.

Figure 3: saveSettings() Function

You have just added a saveSettings() function to sessionstorage.html file. This saveSettings() function will be called through the onclick event of the "Save" button when this button is clicked.

<button type="button" onclick="saveSettings()">Save</button>

The saveSettings() function does the following tasks:

  • Save the current value of the HTML element whose id is "noOfArticleSubscribed" as a key-value pair in the session storage using the setItem() method of the sessionStorage object. If this key does not exist, it will be created else its value will be over-written (update).
    sessionStorage.setItem("noOfArticleSubscribed", document.getElementById("noOfArticleSubscribed").value);
  • Notice the try{} and catch{} duo. They are code to catch any run-time errors (exceptions) that may arise during execution of the code inside the try{} block. What could go wrong? You may ask. Remember the 5MB storage quota for Web Storage that I mentioned earlier. So one possible scenario in this case or rather in any similar cases that involve "save" operation, the intended saved item could have exceed the quota and thus throwing an error. The code that handles any run-time errors is placed inside the catch{} block. We can "catch" the type of error by reading the error message, i.e. "e", and compare it to some pre-determined values to pre-empt any run-time errors dynamically. In this case, we are pre-empting the "QUOTA_EXCEEDED_ERR" error the meaning of which is self-explanatory.
    try {
        sessionStorage.noOfArticleSubscribed = document.getElementById("noOfArticleSubscribed").value;
    } catch (e) {
        if (e == QUOTA_EXCEEDED_ERR) {
            alert("Oop! Not enough storage space.");
        }
    }

    You should always make use of the try{} and catch{} blocks to handle any save or update operations to the Web Storage.

  • That is all that you need to save any items to the Session Storage. Lastly, do not forget to wrap your code inside this
    if (typeof(Storage)!=="undefined")
    Make this checking for browser support of HTML5 Web Storage the de facto practice.

Deleting

We have done the code for reading from and saving to session storage, How can we remove items from the session storage? Add the highlighted code in Figure 4 after the saveSettings() function.

Figure 4: removeSettings() Function

You have just added a removeSettings() function to sessionstorage.html file. This removeSettings() function will be called through the onclick event of the "Clear" button when this button is clicked.

<button type="button" onclick="removeSettings()">Clear</button>

The removeSettings() function does the following tasks:

  • Delete the stored item whose key is "noOfArticleSubscribed" from the session storage by calling the removeItem() method of the sessionStorage object and passing it the item key name of "noOfArticleSubscribed" as parameter.
    sessionStorage.removeItem("noOfArticleSubscribed");
  • Call the init() function to set default value to the HTML element that was previously bound to the value of this deleted stored item.

Testing

Let's launch sessionstorage.html on a browser. I am using Chrome for subsequent illustrations. (Figure 5)

Right click on the browser windows, select "Inspect element" option from the context menu to bring out a new window where you will choose the "Resources" tab to view the session storage.

Figure 5: Session Storage in First Tab

The "file://" origin under the Session Storage node on the left appears empty. Try changing the value in the "No of Article Subscribed" textbox to say 3, clicking the "Save" button, followed by refreshing the browser windows. Do you see what I see in the Session Storage node? (Figure 6)

Figure 6: Session Storage in First Tab

An item has just been created and stored in the session storage. This item bears the key (name) of "noOfArticleSubscribed" and has a value of "3". That is the meaning of a key-value pair. As you add different items, you will see different key-value pairs being created in the session storage.

If you close the current tab and re-launch sessionstorage.html again. You should see that the Session Storage node is empty, and the "No of Article Subscribed" textbox contains "1" (Figure 5). So the message is clear: Session Storage only lives for a single session.

Let's set the first tab back to that in Figure 6 again. Then, launch sessionstorage.html in a second browser tab. You should see the following screen in Figure 7.

Figure 7: Session Storage in Second Tab

This looks like the same screen in Figure 5 - the Session Storage node is empty and the "No of Article Subscribed" textbox contains the default value of "1". If you switch back to the first tab, you will see that the "noOfArticleSubscribed" key of the Session Storage node remains intact as 3 as shown in Figure 6. Try changing the values in the 2 tabs differently and save them, the 2 session storage will each have their own copies of "noOfArticleSubscribed" with different values.

Click the "Clear" button and refresh the browser window in the first tab, you should see the "noOfArticleSubscribed" item vanishes from the Session Storage node of that browser window, and the "No of Article Subscribed" textbox is reverted to the default value of "1". However, its counterpart in the second tab remains intact.

So the message is clear: Session Storage is not shared across multiple sessions.

Make it More Real

Let's take this one step further by submitting sessionstorage.html page to a checkout page which will display a message acknowledging the number of subscription.

Type the following code on the upper part of Figure 8 using a text editor, save it as "checkout_sessionstorage.html" inside a sub-folder called "checkout" of the current folder "html5webstorage", i.e. "html5webstorage/checkout/checkout_sessionstorage.html".

Figure 8: checkout_sessionstorage.html

Move back to sessionstorage.html and add the highlighted code in Figure 9 after the removeSettings() function.

Figure 9: checkout() Function

You have just added a checkout() function to sessionstorage.html file. This checkout() function will be called through the onclick event of the "Check out" button when this button is clicked.

<button type="button" onclick="checkout()">Check out</button>

The checkout() function will redirect the user to checkout_sessionstorage.html page in the sub-folder of "checkout" when the user clicks the "Check out" button on the sessionstorage.html page. (Figure 10)

window.location.assign("checkout/checkout_sessionstorage.html");    
Figure 10: checkout_sessionstorage.html

Upon completion of page load, the onload event of checkout_sessionstorage.html will call its init() function to retrieve the value of item key "noOfArticleSubscribed" from the session storage and display it in a message. (Figure 10) This checkout example has just illustrated one point: Session Storage is shared across different pages of the same session and of the same origin.

Building Local Storage

HTML5 Web Storage provides a localStorage object for working with local storage. localStorage object shares similar methods and properties with the sessionStorage object such as getItem(), setItem(), removeItem(), and length. Therefore, if you are familiar with the session storage, you next journey with local ltorage will be much easier - it is mostly a matter of, believe it or not, "copy and paste".

Open sessionstorage.html in a text editor, save it as "localstorage.html". In localstorage.html,

  • Replace all the sessionStorage object with localStorage object.
  • Change the code in the checkout() function to:
    window.location.assign("checkout/checkout_localstorage.html");

Open checkout_sessionstorage.html in a text editor, save it as "checkout_localstorage.html". In checkout_localstorage.html,

  • Replace all the sessionStorage object with localStorage object.

That's all. You are done with the coding for local storage.

Testing

Let's launch localstorage.html on a browser. (Figure 11)

Figure 11: Local Storage in First Tab

The "file://" origin under the Local Storage node on the left appears empty. Try changing the value in the "No of Article Subscribed" textbox to say 4, clicking the "Save" button, followed by refreshing the browser windows. You should see one key-value pair added to the Local Storage node under the "file://" origin. (Figure 12)

Figure 12: Local Storage in First Tab

Now, launch localstorage.html in a new browser tab. You should see the following screen in Figure 13.

Figure 13: Local Storage in New Tab

This looks like the same screen in Figure 12. If you change the value of subscription in this page and move back to the first tab, you will see that the value of the "noOfArticleSubscribed" key in the Local Storage node, and the value inside the "No of Article Subscribed" textbox will also be updated. If you close all the tabs and re-launch localstorage.html page in a new tab, you should see the same screen as in Figure 12.

Click the "Clear" button and refresh the browser window in the first tab, you should see the "noOfArticleSubscribed" item vanishes from the Local Storage node of that browser window, and the "No of Article Subscribed" textbox is reverted to the default value of "1". If you switch to the second tab, you would see that what had happened to the first tab had also happened to the second tab.

So the message is: Local Storage is permanent and shared across multiple sessions of the same origin.

When the user clicks the "Check out" button on the localstorage.html page, it will be redirected to checkout_localstorage.html page.

Figure 14: checkout_localstorage.html

Upon completion of page load, the onload event of checkout_localstorage.html page will call its init() function to retrieve the value of item key "noOfArticleSubscribed" from the local storage and display it in a message. (Figure 14) This checkout example has just illustrated one point: Local Storage is shared across different pages of the same origin.

Under One Roof

I have placed the property, methods, and event of HTML5 Web Storage in tables 1, 2, and 3 respectively. They are applicable to both the sessionStorage object and the localStorage object.

Storage Properties

Table 1:Storage Property
Property Description / Code Snippets
length

The length property returns the number of key-value pairs currently present in a storage object.

alert(sessionStorage.length); 

Storage Methods

Table 2: Storage Methods
Method Description / Code Snippets
setItem()

The setItem() method attempts to insert a new key-value pair or update the value of an existing key in a storage object.

The setItem() method takes 2 parameters: a key and its associated new value. The method will first check if the given key already exists in the storage object. If it does not, then a new key-value pair will be added to the storage object. If the given key already exists in the storage object, and its current value is not equal to the new value, then its value will be updated to the new value. If its current value is equal to the new value, then the method will do nothing.

In the code below, "noOfArticleSubscribed" is the key while its value is "document.getElementById("noOfArticleSubscribed").value". Always use the setItem() method with the try{} and catch{} duo to detect and handle the "QUOTA_EXCEEDED_ERR".

try {
    sessionStorage.setItem("noOfArticleSubscribed", document.getElementById("noOfArticleSubscribed").value);
} catch (e) {
    if (e == QUOTA_EXCEEDED_ERR) {
        alert("Oop! Not enough storage space.");
    }
}
getItem()

The getItem() method returns the current value associated with the given key in a storage object. It will return null If the given key does not exist in the storage object.

The getItem() method takes one parameter, i.e. a key.

document.getElementById("noOfArticleSubscribed").value = sessionStorage.getItem("noOfArticleSubscribed");
removeItem()

The removeItem() method removes a key-value pair from a storage object. If the key does not exist, this method will do nothing.

The removeItem() method takes one parameter, i.e. a key.

sessionStorage.removeItem("noOfArticleSubscribed");
clear()

The clear() method removes all key-value pairs from a storage object. This method takes no parameters.

sessionStorage.clear();
key()

The key() method takes an integer number as parameter and returns the name of the key whose index position in the key-value list of the storage is equal to the parameter.

<!DOCTYPE HTML>
<html>
<head>
<title>key() Method</title>
</head>
<body>
<h1>List of key-value Pairs in Storage</h1>
<script>
if (typeof(Storage)!=="undefined") {
    
       sessionStorage.setItem("firstName", "Peter");
       sessionStorage.setItem("lastName", "Leow");
       sessionStorage.setItem("gender", "Male");
    
       for (i = 0; i < sessionStorage.length; i++) { 
           var key = sessionStorage.key(i);
           var value = sessionStorage.getItem(key);
           document.write(key + " => " + value + "<br>");
    } 
} else {
        alert("Oop! This browser does not support HTML5 Web Storage.");
}
</script>
</body>
</html>        

Storage Event

When the setItem(), removeItem(), or clear() method is called and actually changes the state of a storage object, a storage event is fired on the window object. Through this storage event, we can track changes in the storage area programmatically. We can add a listener to the event and handle the storage changes in an event handler. However, the event gets fired only on other windows and not on the window where the event is triggered. We will see an interesting example to demonstrate this later on. So hang on and hang in for a little while...

function onStorageEvent(storageEvent){
    document.getElementById("yourMessage").value = localStorage.getItem("message");
}
window.addEventListener('storage', onStorageEvent, false);

The storageEventHandler function is called with a StorageEvent object. This StorageEvent object has the following properties that we can use to find out the details of changes in the storage area programmatically.

Table 3:Storage Event Properties
Property Description
key

The key property returns the name of the key that is added, updated, or removed.

oldValue The oldValue property returns the old value.
newValue The newValue property returns the newly set value.
url The url property returns the URL of the page from where the event originated.
storageArea

The storageArea property returns the storage object whose key is changed, i.e. sessionStorage or localStorage.

Best Practices

We have discussed the essence of HTML5 Web Storage. Let's round up some best practices on how to manage it correctly.

  • Always check whether your browser supports HTML5 Web Storage or not before accessing it.
    if (typeof(Storage)!=="undefined") {
        // Storage related code 
    } else {
        alert("Oop! This browser does not support HTML5 Web Storage.");
    }
  • Always make use of the try{} and catch{} blocks to catch quota exceed error when adding new or updating existing key-value pairs using setItem().
    try {
        sessionStorage.setItem("noOfArticleSubscribed", document.getElementById("noOfArticleSubscribed").value);
    } catch (e) {
        if (e == QUOTA_EXCEEDED_ERR) {
            alert("Oop! Not enough storage space.");
        }
    }
  • The clear() method will wipe up a whole storage object, so use it with extreme care. It is more prudent to use removeItem() instead.
  • When a storage item is remove, it is a necessarily good practice to update the value or state of those HTML elements that reference this item.
  • Take note that Data is stored as strings (Texts) in Web Storage. If you are storing something other than a string, you will have to consciously convert it to their intended data type when you retrieve it. For example, the age of 8 will be automatically stored as letter "8" in the storage:
    var age = 8;
    localStorage["age"] = age; 

    But when we retrieve this item from the storage, we need to convert it back to an integer, using the parseInt() function of JavaScript:

    var age = parseInt(localStorage["age"]);
  • Always use SSL (Secure Sockets Layer) to transmit sensitive information such as credit card numbers, social security numbers, and login credentials across network. Data sent in plain texts between browsers and websites is vulnerable to eavesdropping and DNS spoofing. SSL can be used to prevent this from happening by establishing an encrypted link between a browser and a website.

Tips

Here are some tips on how to code the web storage more efficiently.

  • Instead of using getItem() method of the storage object to read storage item, you can do the shortcut way like this:
    document.getElementById("noOfArticleSubscribed").value = sessionStorage["noOfArticleSubscribed"];
  • Likewise, there are 2 shortcuts to save or update storage item instead of using setItem() method of the storage object:
    sessionStorage["noOfArticleSubscribed"] = document.getElementById("noOfArticleSubscribed").value;
    or
    sessionStorage.noOfArticleSubscribed = document.getElementById("noOfArticleSubscribed").value;
  • You have seen an example of iterating through the key-value lists of a storage object in the key() method of table 2. An shorter way is like this:
    for (var key in sessionStorage) {
        document.write(key + " => " + sessionStorage[key] + "<br>");
    }  
  • Last but not least. Why not create a code template that is pre-written with the must-have code components mentioned in the Best Practices section? I have made one for sessionStorage object below (available for download). You can easily create a similar template for localStorage object by replacing the "sessionStorage" in this template with "localStorage". To use the template, simply replace the "replace with id of an HTML element" and "replace with a key name" placeholders with the actual id and key respectively.
    <!DOCTYPE HTML>
    <html>
    <head>
    <title>Session Storage Template</title>
    <script>
    function init(){
        // Check whether browser supports HTML5 Storage or not
        if (typeof(Storage)!=="undefined") {
            if (sessionStorage.length != 0) { // If storage object is not empty
                document.getElementById("replace with id of an HTML element").value  = sessionStorage.getItem("replace with a key name");
            } else { // If storage object is empty, set default value
                document.getElementById("replace with id of an HTML element").value = '1';
            }
        } else {
            alert("Oop! This browser does not support HTML5 Web Storage.");
        }
    }
    function saveSettings() {
        // Check whether browser supports HTML5 Storage or not
        if (typeof(Storage)!=="undefined") {
            try {
                sessionStorage.setItem("replace with a key name", "replace with a value");
            } catch (e) {
                if (e == QUOTA_EXCEEDED_ERR) {
                    alert("Oop! Not enough storage space.");
                }
            }
        } else {
            alert("Oop! This browser does not support HTML5 Web Storage.");
        }
    }
    function removeSettings() {
        // Check whether browser supports HTML5 Storage or not
        if (typeof(Storage)!=="undefined") {
            // Remove one item from the storage object
            sessionStorage.removeItem("replace with a key name");
            // Call init to reset the HTML elements
            init();
        } else {
            alert("Oop! This browser does not support HTML5 Web Storage.");
        }
    }
    </script>
    </head>
    <body onload="init()">
    
    </body>
    </html>

Wait, don't wash your hands yet lest you miss the fun that is coming up next.

Web Storage Event

You have learned hard. Let's have some fun with HTML5 Web Storage using your newly found knowledge. You will create a simple chat program that works solely using the web storage event. I am using localStorage for this little program. This program has been tested on Firefox version 28.0 and it works like a charm! Seeing is believing, click on the following screenshot (Figure 15) to watch a demo video on this chat program.

Figure 15: Web Storage Chat

Look enticing enough? Then get on to write the code (below) yourself. It is a surprisingly short and simple program that make use of the getItem(), setItem(), and storage event of the localStorage object. You have already learned them earlier. I have intentionaly left out the must-have code that I have mentioned in the Best Practices section, so as not to obscure the gist, that is the chat logic, of this program. However, you should take it as homework to include the must-have Code yourself.

<!DOCTYPE HTML>
<html>
<head>
<title>HTML5 Web Storage Chat</title>
<script>
function get() {    
    document.getElementById("yourMessage").value  = localStorage.getItem("message");
}
function send(){
    localStorage.setItem("message", document.getElementById("myMessage").value);
}
function onStorageEvent(storageEvent){
    document.getElementById("yourMessage").value = localStorage.getItem("message");
}
window.addEventListener('storage', onStorageEvent, false);
</script>
</head>
<body>
<div style="text-align:center">
<h2>HTML5 Web Storage Chat</h2>
<label for="yourMessage">U say</label>
<br>
<input type="text" id="yourMessage" readonly size="40">
<br>
<label for="myMessage">I say</label>
<br>
<input type="text" id="myMessage" autofocus size="40">
<br>
<button type="button" onclick="send()">Send</button>
</div>    
</body>
</html>

To test the program, launch it separately in 2 separate (Firefox) browser window, place them side-by-side as shown in the video. The logic of the code works as follows:

  • When the send button in the first browser window is clicked, the message from the "I say" textbox will be saved to the localStorage object with the key name "message". This causes a change in the state of the localStorage object
  • This change triggers a storage event on the second (Firefox) browser window that calls the onStorageEvent() function
  • The onStorageEvent() function will retrieve the value of the key named "message" from the localStorage and assign it to the "yourMessage" textbox labeled as "U say"
  • The process is vice versa when the message is sent from the second window.

Have fun!

Remember Me

I have developed another program called "Remember Me" (Figure 16) to illustrate the use of web storage to remember user's settings.

Figure 16: Remember Me

This program allows a user to set the background color of the circle and the font weight of the number texts. When the Save button is clicked, the page will take on the new settings which will also be saved to the local storage. When the user re-visit the page again, it will show these settings. Look up for the code related to the local storage. You should recognize them.

<!DOCTYPE html>
<html>
<head>
<title>Remember Me</title>
<script>
    var backgroundColor;
    var fontWeight;    
    var canvas;
    var context;
    var second;
    function init() {
        applySettings();    
        document.getElementById('backgroundColor').value = backgroundColor;
        document.getElementById('fontWeight').value = fontWeight;        
        canvas = document.getElementById("canvas");
        context = canvas.getContext("2d");        
        second = 0;
        // Set a timer to run the draw() function every one second
        timer = setInterval(draw, 1000);
        return timer;
    }
    function draw() {
        // Clear the canvas
        canvas.width = canvas.width;
        context.beginPath();
        // Draw a circle
        context.arc(150, 100, 70, 0, 2 * Math.PI);
        context.fillStyle = backgroundColor;        
        context.fill();
        // Define font and draw texts
        context.font = fontWeight + 'px Arial';
        context.fillStyle = "black";
        context.fillText('12',137,50);
        context.fillText('3',201,110);
        context.fillText('6',143,161);
        context.fillText('9',88,110);
        // Set origin of canvas to 150, 100
        context.translate(150, 100);
        context.moveTo(0, 0);
        // Rotate and draw a line
        context.rotate(6 * second * Math.PI / 180);
        context.lineTo(0, -60);
        context.strokeStyle = "black";
        context.stroke();
        // Increase one second         
        second = (second + 1) % 60;
    }
</script> 
<script>
function saveSettings() {
    // Check whether browser supports HTML5 Storage or not
    if (typeof(Storage)!=="undefined") {
        try {
                backgroundColor = document.getElementById('backgroundColor').value;
            fontWeight = document.getElementById('fontWeight').value;
               localStorage.setItem('backgroundColor', backgroundColor);
             localStorage.fontWeight = fontWeight;
        } catch (e) {
            if (e == QUOTA_EXCEEDED_ERR) {
                alert('Oh no! No more storage space already.');
            }
        }
    } else {
        alert('Oop! This browser does not support local storage');
    }
}
function applySettings() {
    if (localStorage.length != 0) {
            backgroundColor = localStorage.getItem('backgroundColor');
        fontWeight = localStorage.fontWeight;
    } else {
        backgroundColor = '#ffffff';
        fontWeight = '12';
    }
    document.getElementById('backgroundColor').value = backgroundColor;
    document.getElementById('fontWeight').value = fontWeight;
}
function clearSettings() {
    localStorage.removeItem("backgroundColor");
    localStorage.removeItem("fontWeight");
    applySettings();
}
</script>
</head>
<body onload="init();" style="text-align: center; color: blue;">
    <h2>Remember Me</h2>
    <div>
        <canvas id="canvas" width="300" height="200"
            style="border: 1px solid #000000;">
             Oops, this browser does not support canvas.
          </canvas>
    </div>
    <div>
        <form>
            <label for="backgroundColor">Background Color</label>
             <input type="color" id="backgroundColor" value="#ffffff">
            <br>
            <label for="fontWeight">Font Size</label>
             <input type="number" id="fontWeight" max="20" min="10" value="12">
             <br>
            <button type="button" onclick="saveSettings()">Save</button>
            <button type="button" onclick="clearSettings()">Reset</button>
         </form>    
    </div>
</body>
</html>

Checking Out

Once again, you have conquered a new ground of knowledge victoriously. It is time to check out and take a well-deserve breather. I shall return. Until then... Java | [Coffee]

P.S. Oh yes, do not forget to wash your hands. Big Grin | :-D

Reference

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Peter Leow
Instructor / Trainer
Singapore Singapore
子曰:"三人行,必有我师焉;择其善者而从之,其不善者而改之

"There is always something we can learn from another person. Choose to follow his strengths while use his shortcomings to reflect upon ourselves."
― Confucius

“Live as if you were to die tomorrow. Learn as if you were to live forever.”
― Mahatma Gandhi

You may also be interested in...

Comments and Discussions

 
GeneralThoroughly covered and well Pin
James Jensen13-May-14 11:58
professionalJames Jensen13-May-14 11:58 
GeneralRe: Thoroughly covered and well Pin
Peter Leow14-May-14 23:29
professionalPeter Leow14-May-14 23:29 
GeneralMy vote of 5 Pin
ridoy5-May-14 8:48
professionalridoy5-May-14 8:48 
GeneralRe: My vote of 5 Pin
Peter Leow6-May-14 4:11
professionalPeter Leow6-May-14 4:11 
QuestionNice Pin
Manas Bhardwaj4-May-14 22:39
professionalManas Bhardwaj4-May-14 22:39 
AnswerRe: Nice Pin
Peter Leow4-May-14 22:59
professionalPeter Leow4-May-14 22:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150819.1 | Last Updated 5 May 2014
Article Copyright 2014 by Peter Leow
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid