Using the Back and Forward Buttons Using the History API

I have the following test application: http://dev.driz.co.uk/ajax/

You can click download links on other pages using jQuery AJAX, and there are two types: globalTabs and localTabs that load content into different panels. NOTE. Each page is actually a full page, but we use only what we want using the jQuery search method.

To improve this, I use the HTML5 History API (History.js for cross-browser).

The headers and URLs change perfectly, and the history stack is pressed successfully, and when I use the back and forward buttons, the URL and title will go back.

Now the complex part is loaded back into the content from the previous state and the more complex loading of the correct type, for example. global or local ajax. To achieve this, I think I need to pass BOTH data and type into a push state so that it can be reused for popstate ...

Can anyone help point me in the right direction? I have all the first parts of the job, just the case of getting this ajax type transmission for pushState and then reusing it with popstate change.

To improve this, I rewrite it as follows to show my plan for transferring type and data:

NOTE: capitalization history is because I use History.js

var App = { init: function() { $(document).ready(function() { $('.globalTabs li a').live('click', function (e) { e.preventDefault(); App.globalLoad( $(this).attr('href') ); }); $('.localTabs li a').live('click', function (e) { e.preventDefault(); App.localLoad( $(this).attr('href') ); }); }); window.addEventListener('popstate', function(event) { // Load correct content and call correct ajax request... }); }, localLoad: function ( url ) { $.ajax({ url: url, success: function (responseHtml) { $('.localContent').html($(responseHtml).find('#localHtml')); $data = { $(responseHtml).find('#localHtml'), 'local'}; History.pushState($data, $(responseHtml).filter('title').text(), url); } }); }, globalLoad: function ( url ) { $.ajax({ url: url, success: function (responseHtml) { $('.mainContent').html($(responseHtml).find('#globalHtml')); $data = { $(responseHtml).find('#globalHtml'), 'global'}; History.pushState($data, $(responseHtml).filter('title').text(), url); } }); } }; App.init(); 

UPDATE: To clarify this issue, these are two issues that I am asking for help with.

1.) Get back and forth buttons that work with ajax requests so that they load the correct data back into the content area.

2.) Loading the content into the correct area by passing the content using the pushState method so that it knows if it is a global div or local div request.

+8
jquery ajax
source share
2 answers

The data object is erroneous, so you get this problem. The object is defined by the key, a pair of values:

 object = {key:'value'}; $data = { text:$(responseHtml).find('#globalHtml'), type:'global', url:'the_url'}; 

not

 $data = { $(responseHtml).find('#globalHtml'), 'global'}; 

Using the definition of an object, you will return your data using History.getState ()

 History.Adapter.bind(window,'statechange',function(){ var data = History.getState().data; if(data){ var html = data.text; var type = data.type; var type = data.url; if(html && type){ if(type == 'global'){ // just change html $('.mainContent').html(html); // call the App object function if(url) App.localLoad(url); }else{ $('.localContent').html(html); } } } }) 

NOTE:

  • when the statechange event is fired, if any data is present, it will trigger ajax calls
  • to mimic ajax call without forcing it to just change the name, I think it will cover it

EDIT

  • the data object is actually taken from History.getState (). data not History.getState ()
  • added one more parameter for saved object to save url
  • using the url and type, you can call the same function as in the onClick event

PROBLEM:

Uncaught TypeError: convert circular structure to JSON

The object is referencing somewhere; hence the message “circular structure”. This means that you are trying to create an object that has a reference to itself, usually this happens with DOM elements. You should really consider changing

 $data = { $(responseHtml).find('#localHtml'), 'local'}; 

in

 $data = { html:$(responseHtml).find('#localHtml').html(), type:'local'}; 

Pay attention to the keys for the object (html and type) and the call to the html function (.html ()), this way you do not send unnecessary data, just html. If you need to use html data when loading as a DOM object, just use this:

 var DOM_Element_loaded = $('<div>').html(html_loaded); 

Now you can use DOM_Element_loaded to search / process data in the downloaded html without having to attach it to the body.

+12
source share

NOTE : this is more of a comment than an answer, but you will get better syntax highlighting with answer responses.

This is what I did when I ran into this problem. If I remember correctly, this prevented the double query problem.

 window.onpopstate = function(event) { if (event.state && event.state.initialHref) { // make an AJAX request // URL for AJAX request is event.state.initialHref } } 

When I use history.pushState() / history.replaceState() , I define the initialHref property in the object for the first argument. I am using an absolute URL for this value, not a relative one.

0
source share

All Articles