agamemnus / history-easy.js

Easy HTML5 history wrapper for modern (IE10+) browsers.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

history-easy.js

This is a wrapper for the Javascript HTML5 history API for modern and updated browsers -- Firefox, Chrome, Safari, Opera, and IE10+.

What's it for, and why use it?

1) It provides an automatic way for handling the back button.
2) It allows you to bundle state data with URLs, titles, and inline callbacks.
3) Extras include a streamlined structure for you to handle (or prevent) history state changes via an "onbeforestatechange" function, "onstatechange" function, and a default state variable.
4) You can customize it, modify it, or transmogrify it: it is public domain, and the code base is about 140 lines, with the core less than 100 lines.

If you found this function useful, financial support is always appreciated: https://www.gittip.com/agamemnus/

The license is public domain.

Table of Contents

Short Example Code
Control Flow, Simplified
Control Flow, Detailed/Extensive

Example Code

Check out this code or view the interactive example -- with slightly more code.

var history_control = new history_control_object ({
 'onstatechange' : function (new_state, callback) {
  document.body.innerHTML = new_state.fruit
  callback ()
 }
})
 
history_control.load_page (
 {fruit: 'Current fruit: "apple". Changes to "pear" in 2 seconds.'},
 {url: 'apple', title: 'Apple.', callback: function () {console.log ("The page changed.")
  setTimeout (function () {
   history_control.load_page ({fruit: 'Current fruit: "pear". Try the back button!'}, {url: 'pear', title: 'Pear.'})
  }, 2000)
 }}
)

Control Flow, Simplified

See example and/or code. In summary:

1) Create a new function object, then use .load (state, settings).
2) The wrapper adds a title, URL, and custom callback attribute for each entry hash. To set these, populate the settings object when using .load_page: .title, .new_url, and .callback.
3) The function object runs .onbeforestatechange, if it is defined. If there's no callback in that function, the new history loading process ends. The callback continues the new history loading process.
4) The function changes the state and adds the title/url/custom callback attribute.
5) The function runs .onstatechange, if it is defined.
6) The function runs the custom callback, if it is defined. (as a callback -- the second parameter of .onstatechange)

Control Flow, Detailed/Extensive

Note: throughout the documentation, the new history object will be referred to as "history_main".

First, a new instance of history_control_object must be created. For example:

var history_main = this.history_control = new history_control_object ({
 // Determines if the first call to .page_load should overwrite the provided new_state with the initial window.location. (true) This is true by default.
 'overwrite_first_state': true,
 // Function called before history changes. To prevent continuation, simply don't run the callback.
 'onbeforestatechange' : function (new_state, settings, callback) {
  // <Your code here.>
  //  ...
  // </Your code here.>
  callback () // If this isn't run, the history load does not continue.
 },
 // Function called when the history changes.
 'onstatechange' : function (new_state, callback) {
  // <Your code here.>
  //  ...
  // </Your code here.>
  callback () // Should finish by running any optionally defined callback.
 },
 // The "var_name" variable will be a property of history_main and accessed/modified
 // as if it was a history state value.
 'var_name'      : 'page',
  // "initial_page" is the initial page value for the "var_name" property variable.
 'initial_page'  : 0,
 'base_filename' : '',
 // (4) a persistent variable holding the URL GET variables.
 'app_url_vars'  : test_main.app_url_vars
})


At any time, history_main's .overwrite_first_state, .base_filename, .onbeforestatechange, .onstatechange, .initial_page, .app_url_vars, .title, .url, and .callback are significant properties that can be accessed or modified.

There is one built-in exposed function property in the history object:
history_main.load_page (new_state, settings)
This "loads" a new page with the specified history state (new_state) and settings. new_state should be an object with string properties. This represents the HTML5 history state. The history_main.load_page function is not destructive towards its parameters: it shallow the copies both new_state and settings variables.

In the first call to history_main.load_page, new_state is overwritten by window.location's URL parameters. E.G.: "mypage.htm?page=apples" sets new_state to {page: 'apples'}, by default. Setting the history_main.overwrite_first_state property to a boolean "false" will prevent the default overwrite.

Similarly, in the first call to history_main.load_page, history_main[var_name] (by default, new_state['page']) is set to history_main.initial_page.

new_state[var_name] is then set to history_main[var_name] if new_state[var_name] is undefined.

After these variables are set (or not), the user-supplied history_main.onbeforestatechange function is run, if it exists. If it does not exist, the code jumps to the internal set_page_state function. history_main.onbeforestatechange has 3 parameters: new_state, settings, and callback. new_state and settings are the shallow-copied variables supplied in history_main.load_page. callback is the function that should be called to continue the page load sequence.

Continuing from history_main.load_page or clicking the back button of the browser directs the loading sequence to set_page_state, which has the familiar parameters new_state, settings, and the record_history parameter. record_history is true if arriving from history_main.load_page and false if arriving from the back button event handler. (formally, a window "popstate" event listener)

The set_page_state function checks options for the parameters title, url, and callback. If any of those are set, or if these parameters were set via history_main (eg: history_main.title = "Apples"), they are added internally as pairings to the current state. The title parameter sets the document's title, url sets the visible URL, and callback is a function that is run at the end of the page load. These variables are saved and bound to the current new_state such that clicking the "back" button gets and runs these saved parameters.

If the set_page_state function was called from the popstate event listener, history_main[var_name] is set to new_state[var_name].

The actual HTML5 history API is now invoked: replaceState if it is the first time it is invoked, and pushState otherwise -- with the accompanying page state, title, and URL. The URL is set to options.url (with a base of location.protocol + '//' + location.host + location.pathname + history_main.base_filename) if options.url exists; otherwise, it is the hash of the new_state variable.

After the HTML5 history API is invoked, history_main.onstatechange is run.
If history_main.onstatechange is not defined, the callback function specified in options is immediately run, and the page load is complete.

If history_main.onstatechange is defined, it is run with a new_state parameter and a secondary options.callback parameter. options.callback is not called within the set_page_state function in this case: it must be invoked within history_main.onstatechange.

About

Easy HTML5 history wrapper for modern (IE10+) browsers.

License:The Unlicense


Languages

Language:JavaScript 92.5%Language:HTML 7.5%