I have the following test application: http://dev.driz.co.uk/ajax/
You can click the links to load in other pages using jQuery AJAX and there are two types, globalTabs and localTabs which load in content into different panels. NOTE: That each page is actually the full page but we only grab the content we want using jQuery find method.
To enhance this I am using the HTML5 History API (History.js for cross-browser).
The titles and urls change fine and the history stack is being pushed to successfully and when I use the back and forward buttons the url and title does revert back.
Now the complicated part is loading back in the content from the previous state and more complicated loading the correct type e.g. global or local ajax. To achieve this I am thinking I need to pass BOTH the data and the type to the push state so that it can be reused again for the popstate...
Can anyone help point me in the right direction? I have all the first parts working, just a case of getting this passing of the ajax type to the pushState and then reusing it with the popstate change.
To improve on this I rewriting it as follows to show my plan for passing the type and data:
NOTE: the uppercase History is because I'm using 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 question, they're are two problems I seek help with.
1.) Get the back and forward buttons working with the ajax requests so they load the correct data back into the content area.
2.) Loading the content into the correct area by also passing the content with the pushState method so that it knows if it's a global div or local div request.
back() is the same as history.go(-1) . history. back() is the same as clicking "Back" your browser.
The History back() method in HTML is used to load the previous URL in the history list. It has the same practical application as the back button in our web browsers. This method will not work if the previous page does not exist. This method does not contain any parameter.
The DOM Window object provides access to the browser's session history (not to be confused for WebExtensions history) through the history object. It exposes useful methods and properties that let you navigate back and forth through the user's history, and manipulate the contents of the history stack.
the data object is wrong, that is why you get that problem. An object is defined by key,values pair:
object = {key:'value'};
$data = { text:$(responseHtml).find('#globalHtml'), type:'global', url:'the_url'};
not
$data = { $(responseHtml).find('#globalHtml'), 'global'};
Using the object definition you will get your data back 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's function
if(url) App.localLoad(url);
}else{
$('.localContent').html(html);
}
}
}
})
NOTE:
EDIT
PROBLEM:
Uncaught TypeError: Converting circular structure to JSON
An object is referencing itself somewhere; hence the message "circular structure.". That means you are trying to stringify a object that has a reference to itself, this usualy happens with DOM elements. You should really consider changing
$data = { $(responseHtml).find('#localHtml'), 'local'};
to:
$data = { html:$(responseHtml).find('#localHtml').html(), type:'local'};
Notice the keys for the object (html and type) and the html function call (.html()), this way you wont send unnecessary data, just the html. If you need to use the html data when loading it as a DOM object just use this:
var DOM_Element_loaded = $('<div>').html(html_loaded);
now you can use DOM_Element_loaded to search/manipulate data in the html loaded without needing to attach it to the body.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With