Introduction to the HTML5 History API

Original author: Mike Taylor, Chris Mills
  • Transfer
Before HTML5, the only thing we could not control and manage (without reloading content or hacks from location.hash) was the history of one tab. With the advent of the HTML5 history API, everything has changed - now we can walk around the history (earlier we could too), add elements to the history, respond to transitions along the history and other usefulnesses. In this article, we will look at the HTML5 History API and write a simple example illustrating its capabilities.

Basic concepts and syntax


The History API relies on one DOM interface - the History object. Each tab has a unique History object, which is located in window.history. History has several methods, events, and properties that we can control from JavaScript. Each tab page (Document object) is an object of the History collection. Each element of the story consists of a URL and / or state object, may have a title, Document object, form data, scroll position and other information associated with the page.

The main methods of the History object:
  1. window.history.length: Number of entries in the current history session
  2. window.history.state: Returns the current history object
  3. window.history.go(n): A method that allows you to walk around history. The argument is the offset relative to the current position. If 0 is passed, the current page will be updated. If the index goes beyond history, then nothing will happen.
  4. window.history.back(): Method identical to calling go(-1)
  5. window.history.forward(): Method identical to calling go(1)
  6. window.history.pushState(data, title [, url]): Adds a story item.
  7. window.history.replaceState(data, title [, url]): Updates the current history item.

To go 2 steps back in history, you can use:
history.go(-2)

To add story items, we can use history.pushState:
history.pushState({foo: 'bar'}, 'Title', '/baz.html')

To change the history record, we can use history.replaceState:
history.replaceState({foo: 'bat'}, 'New Title')

Living example


Now we know the basics, let's look at a live example. We will do a web file manager that will allow you to find the URI of the selected image ( see what happens at the end ). The file manager uses a simple file structure written in JavaScript. When you select a file or folder, the picture is dynamically updated.
image
We use data-*attributes to store the title of each image and use the dataset property to get this property:
  • crab2.png

  • For everything to work quickly, we load all the pictures and update the attribute srcdynamically. This acceleration creates one problem - it breaks the button back, so you cannot go forward or back through the pictures.

    HTML5 history comes to the rescue! Each time we select a file, a new history record is created and the locationdocument is updated (it contains a unique image URL). This means that we can use the back button to bypass our images, while in the address bar we will have a direct link to the picture, which we can save to bookmarks or send to someone.

    The code


    We have 2 divas. One contains the folder structure, the other contains the current picture. The entire application is managed using JavaScript. Only the most important points will be highlighted. The source code for the example is very short (about 80 lines), see it after reading the whole article.

    The method bindEventshangs handlers for the event popstatethat is called when the user goes through the history and allows the application to update its state.
    window.addEventListener('popstate', function(e){
      self.loadImage(e.state.path, e.state.note);
    }, false);
    

    The object eventthat is passed to the event handler popstatehas a property state- this is the data that we passed as the first argument pushStateor replaceState.

    We attach the event handler to clickthe div that represents our file structure. Using the delegation of events, we open or close the folder or upload a picture (with the addition of an entry in the history). We look at the classNameparent element in order to understand which of the elements we clicked on:
    - If this is a folder we open or close it
    - If this is a picture, then we show it and add a history element

    dir.addEventListener('click', function(e){
      e.preventDefault();
      var f = e.target;
      // Это папка
      if (f.parentNode.classList.contains('folder')) {
        // Открываем или закрываем папку
        self.toggleFolders(f);
      } 
      // Это картинка
      else if (f.parentNode.classList.contains('photo')){
        note = f.dataset ? f.dataset.note : f.getAttribute('data-note');
        // отрисовываем картинку
        self.loadImage(f.textContent, note);
        // добавляем элемент истории
        history.pushState({note: note, path:f.textContent}, '', f.textContent);
      }
    }, false);
    

    The method that modifies the contents of an image and updates its signature is very simple:
    loadImage: function(path, note){
        img.src = path;
        h2.textContent = note;
    }
    

    We got a simple application that demonstrates the capabilities of the updated object interface History. We use the pushStatepopstate event to update the page content to add a story item. In addition, when we click on a picture, we get its actual address in the address bar, which we can save or send to someone.

    When can I use it?


    Firefox 4+
    Safari 5+
    Chrome 10+
    Opera 11.5+
    iOS Safari 4.2+
    Android 2.2+
    IE ???
    List of browsers supporting history API

    Where is it used?


    1. Facebook
    2. Github - navigation through the project tree
    3. ???

    Read


    1. Manipulating History for Fun & Profit
    2. WHATWG HTML5 history API
    3. W3C history API Spec
    4. MDC Manipulating the browser history
    5. History.js - the script emulates the HTML5 history API (location.hash magic) in those browsers that have it do not support

    Also popular now: