Local Storage and Event Binding


Goal

By the end of today, you will be able to:

  1. use the LocalStorage API to store information in the browser
  2. use stored information to remember and implement a user's preferences.

Event Binding

We've seen event binding before, when we first introduced events and event handlers. There are two ways to have a function, say fred, be invoked when a button is clicked:

  • The old-fashioned, in-line way:
    <button type="button" onClick="fred();">
    
    <script>
      function fred () { ... }
    </script>
    
    
  • The new, modern, external way:
    <button type="button" id="doit">
    
    <script>
      function fred () { ... }
    
      document.querySelector("#doit").onclick = fred;
    </script>
    
    

(For you pedants, these are not exactly the same, but for our purposes they are.)

Advantages of the new way:

  • JavaScript code is kept entirely separate from the HTML
  • The event handler can easily be attached (bound) to multiple elements. For example, we could attach one to every item in an HTML list like this:
    var elts = document.querySelectorAll("#mylist > li");
    for( var i=0; i < elts.length; i++ ) {
        var li_elt = elts[i];
        li_elt.onclick = fred;
    }                  
    

List of reasons:

  1. cool

  2. shiny

  3. new

  4. modern

The fancy feature where I can click on a quiz answer and make it disappear is done using event binding and a kind of compact notation like that loop above. If I only had inline event handlers, it would be so tedious that I simply wouldn't do it. With event binding, it's automagic.

Local Storage Concept Review

Local Storage is a departure from most of our JavaScript because we are interacting with something outside the little world of JavaScript and the document.

Furthermore, it can be weird and hard to debug because restarting the browser doesn't reset everything. Before in this course, you could always start over by reloading the page, but no longer. That's because local storage is sticky.

Method/
Property
Usage Example
.length localStorage.length
The number of items stored in the storage.
.setItem() localStorage.setItem("zip", "02481")
Stores an item as a pair of a key and value.
.getItem() localStorage.getItem("zip")
Retrieves the value stored under the key that is passed as an argument to the method.
.clear() localStorage.clear()
Removes all items stored in the local storage.
.removeItem() localStorage.removeItem("zip")
Removes only one item, whose key is passed as the argument.
.key() localStorage.key(1)
Retrieves the name of the key with index 1 (imagine that keys are stored in a array and we can access each of them through the index).

Quiz Question Nr. 1

The JavaScript on a page executes the following code:

  var year = localStorage.getItem("year");

What value does year have?

  1. the number 2014
  2. the string "2014"
  3. undefined
  4. it depends on what was previously stored, if anything

Quiz Question Nr. 2

We want to keep a visits counter on a page, so we write the following code, but it doesn't do the right thing. Why not?

        var numPrior = localStorage.getItem("numPriorVisits");
        var numPrior = numPrior + 1;
        localStorage.setItem("numPriorVisits", numPrior);
      
  1. the method to store a value is called putItem
  2. We need to set the item before we get it
  3. We need to use parseInt on the value
  4. We need to .clear() the localStorage first

Quiz Question Nr. 3

LocalStorage is a lot like using global variables except ...

  1. global variables disappear when the browser tab is closed
  2. local storage has a fixed length
  3. local storage is local to a single function
  4. local storage has to be initialized before it can be used

Quiz Question Nr. 4

Suppose we have a DIV on the page like this:

    <div id="fred"> ... <div>
  

We want to have the doStuff function executed whenever Fred is clicked on. How can we do that?

  1. rewrite the div to be
        <div id="fred" onclick="doStuff" > ... <div>
      
  2. rewrite the div to be
        <div id="fred" onclick="doStuff();" > ... <div>
      
  3. In our JS code, do this:
      document.querySelector("#fred").onclick = doStuff();
    
  4. In our JS code, do this:
      document.querySelector("#fred").onclick = doStuff;
    

Saving User Preferences

For accessiblity reasons, many professional websites have a way to increase or decrease the font size. We're going to do that.

First, try the following

example of setting the font size

Let's look at the code:

var fontSize=12;  // in px

function changeFontSize(diff) {
    fontSize = fontSize + diff;
    document.body.style.fontSize=fontSize+"px";
    console.log("font set to "+fontSize);
}

function increase() {
    console.log("increasing");
    changeFontSize(+1);
}

function decrease() {
    console.log("decreasing");
    changeFontSize(-1);
}

function setup() {
    console.log("set up");
    changeFontSize(0);
    document.querySelector('#bigger').onclick = increase;
    document.querySelector('#smaller').onclick = decrease;
}

window.onload = setup;

// to work in jsFiddle, we need to invoke setup() ourselves, since there 
// is no "window" object (our code is inside the panes of jsFiddle).
  

What questions do you have?

Exercise 1

Open the jsFiddle.

Alternatively:

Download the following files to your computer:

Do the following

  1. Make sure the downloaded file works correctly. (if using the files)
  2. Figure out how to save the desired font size in the local storage.
  3. Figure out when that should happen.
  4. Implement the saving of the font size.
  5. Check in the browser inspector to see if this worked.
  6. When the setup happens, read the saved font size (if any). Remember that getItem returns null if there is no value.
  7. Set the font size to that saved value.

Your solution might work like this:

example of setting and storing the font size

Summary

We hope that after these activities you have a good understanding of:

  • how to save values in local storage
  • how to read values from local storage
  • how to set up event handlers