PushState () and popState (): managing browser history

I am working on a small project in which I want to create an Ajax style website. Content is loaded using jQuery load() . As some of you know, the downside of this is that the URL does not change according to the content displayed. You can use pushState() to do this work. Since this does not support cross browser, I used the history.js plugin.

This works very well, but the problem is that my back and forth buttons do not work as they should, and I have no idea what I'm doing wrong. The URL changes correctly, but the content does the same, but the title does not change at all. With the title, I mean what appears as the title of the window (or tab) of the browser window. That is, the <title> loaded page or the title attribute of the link that links to this page (they are the same). I think this is due to the fact that I only call the part of the page whose title I need (i.e. by adding #content to load() ). I still want the title of this page. Here is an example of what I have so far. (No longer available since December 28, 2013.) jQuery file:

 $(document).ready(function () { var firstLink = $("ul > li:first-child > a"); var menuLink = $("ul > li > a"); var firstLoadedHtml = firstLink.attr("href") + " #content"; $("#sectionContainer").hide().load(firstLoadedHtml).fadeIn("fast"); firstLink.addClass("active"); menuLink.click(function(e) { history.pushState(null, null, this.href); e.preventDefault(); e.stopImmediatePropagation(); var CurLink = $(this); var newLoadedHtml = CurLink.attr("href") + " #content"; var oldSection = $(".contentPage"); $("#sectionContainer").hide().load(newLoadedHtml).fadeIn("fast"); menuLink.removeClass("active"); CurLink.addClass("active"); }); $(window).bind('popstate', function() { var returnLocation = history.location || document.location; $('#sectionContainer').load(returnLocation + "#content"); }); }); 

I also noted that when returning to the main page (i.e. / sectionLoaderTest /) it is empty for a while, and only after a while the contents of the first page are loaded. Is there any way to optimize this?

In addition, I use jQuery to add the active class to the link that was clicked. How can I make sure this changes in line with the story? So, if the correct link is highlighted when the user is moved again?

So, three questions:

  • Get the name while working while going back and forth
  • Optimize main page load time
  • Fix active class when moving forward and backward

All help is appreciated!

NOTE 1 I would like to use history.js and my own script and support browser support < HTML5 . I would prefer this because 1. I know that this should work, there is something that is going wrong. 2. This will save time if I can see one solution and implement it in a script that I already wrote, rather than calculating a completely new script.

NOTE 2 : Generosity will only be granted to someone who can answer all my questions (3)!

+6
jquery html5 pushstate popstate
source share
2 answers

Answer 1 - Get the name while working forward and backward

As I understand it, you want to change the title of the html document from the link, is loaded into the div. When you upload a file to a div via jQuery .load , you simply insert the full response text after the ajax request. Thus, with all things that should not be in a div, like a title tag or meta . However, the title of the current document ( http://bramvanroy.be/sectionLoaderTest/index.html ) is defined in the title , which is inside the head tag, and not in the title tag inside the div, so the name of the document does not change.

So how can I fix this?

Good question, because the title element inside the div element is not valid, most browsers will remove it, so you cannot just use this:

 document.title = $("#sectionContainer title").text(); 

since the title element may not exist.

So, we need a direct answer from the jQuery .load function. I can get it by adding a callback argument to the function:

 $("#sectionContainer") .hide() .load(newLoadedHtml, function(responseText) { document.title = $(responseText).filter("title").text(); }) .fadeIn("fast"); 

What you may not understand, therefore I use the .filter function, not .find . This is because jQuery is a parsing of the html , head and body tags from html, but does not remove the children.

Answer 2 - Optimizing the loading time of the main page

The document is loaded from top to bottom.

So, first of all you need to load CSS, JavaScript, etc., and then the main document. Since jQuery always waits for a document to execute, it would be a very bad idea to put all your script elements right to the end of the body so that your HTML can be loaded earlier.

BtW I had this problem for the first time after everything was cached and the document loaded very quickly.

Answer 3 - Correct the active class when moving forward and backward

I would say that the loop goes through the href attributes of a elements and compares them with the data from History.getState() . It should be easy.

You made some mistakes in your code - your fixed code:

You have added the #content hash to all the urls .. this doesn't make sense and it will be deleted again using jQuery: https://github.com/jquery/jquery/blob/master/src/ajax.js#L617 ( comes from the line: 158, 190, 337, 617 - the blur is on line 6)

 $(document).ready(function () { var firstLink = $("ul > li:first-child > a"); var menuLink = $("ul > li > a"); var firstLoadedHtml = firstLink.attr("href"); $("#sectionContainer").hide().load(firstLoadedHtml).fadeIn("fast"); firstLink.addClass("active"); menuLink.click(function(e) { e.preventDefault(); e.stopImmediatePropagation(); var newLoadedHtml = $(this).attr("href"); History.pushState(null, newLoadedHtml, newLoadedHtml); $("#sectionContainer") .hide() .load(newLoadedHtml, function(responseText) { document.title = $(responseText).filter("title").text(); }) .fadeIn("fast"); }); History.Adapter.bind(window, "statechange", function() { menuLink.removeClass("active"); $("a[href='" + History.getState().title + "']").addClass("active"); $('#sectionContainer').load(document.location.href, function(responseText) { document.title = $(responseText).filter("title").text(); }); }); }); 
+11
source share

You can also try available routing plugins like davis.js or jQuery Pusher https://github.com/salvan13/jquery-pusher

0
source share

All Articles