Handling hash with HTML5 History API
Asked Answered
S

2

6

I am using the history.js plugin here: https://github.com/browserstate/history.js/ for handling HTML5 History in my application. And I want to handle both HTML5 and HTML4 versions (using the hash fallback).

You can see the demo here: http://dev.driz.co.uk/history45/


Question 1

How do I load the correct content based on the hash when a person visits a url with a hash in (hasn't clicked a link on the website) As the server won't understand what the code is and I don't want to have to double the request by checking if the hash exists and then calling the content via AJAX. So for example: http://dev.driz.co.uk/history45/#about.php doesn't load in the about.php content.

Update:

I've seen some examples here: https://gist.github.com/balupton/858093 which seem to cover loading the correct content (even optimised versions). But I'm struggling to get it to work in combination with my HTML5 version. View source: http://dev.driz.co.uk/history45/ AND it only runs when a person clicks a link instead of on page load which is the original issue.

Update 2:

Tried an example here: http://dev.driz.co.uk/history4/#/contact.php to get the content to load in contact.php content using the snippet in the source but doesn't work...? BUT according to the article here: https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling#wiki-why-the-hashbang-is-unnecessary this code SHOULD be AJAX loading in the correct content if it has a hash on it. Any ideas why?


Question 2

How do I force the /#/ on the root and prefix all urls with `#/'

As currently if you try and visit a page via a link in a HTML4 browser, you end up with weird urls like:

http://dev.driz.co.uk/history45/#contact.php and http://dev.driz.co.uk/history45/#./

instead of:

http://dev.driz.co.uk/history45/#/contact.php and http://dev.driz.co.uk/history45/#/


And if I start on an inner page with:

http://dev.driz.co.uk/history45/contact.php and choose a link then I end up with: http://dev.driz.co.uk/history45/contact.php#about.php when what it should be is: http://dev.driz.co.uk/history45/#/about.php

Sherbrooke answered 11/2, 2014 at 23:18 Comment(0)
T
3

How do I load the correct content based on the hash when a person visits a url with a hash in (hasn't clicked a link on the website) As the server won't understand what the code is

The server won't see the # or anything after it

and I don't want to have to double the request by checking if the hash exists and then calling the content via AJAX.

Your only other option is to redirect (by setting location with JavaScript) to the URL that you would have used if the history API was available.

How do I force the /#/ on the root?

You'd have to redirect to the homepage (again by setting location) if the history API isn't supported.


I take the view that if they are using a browser which doesn't support the history API (which probably means Windows XP and IE 8 these days) then they can get the non-Ajax fallbacks and I never have to deal with the hash hack.

Teyde answered 11/2, 2014 at 23:23 Comment(4)
I've updated with OP with some more examples of what I have tried to get question 1 working along with a test. But it's not loading in the content when doing the hash?Sherbrooke
Also with regards to HTML5 support. The API isn't supported by IE until IE10.Sherbrooke
@Sherbrooke — Yes, but there are very few IE9 users since most of them get auto-updated. It is XP users who get stuck on IE8.Teyde
Unfortunately the client I am building this for is a University which is locked down to IE8 on 80% of their machines and IE9 for the rest.Sherbrooke
I
1

If all you want to do is to force all browsers (both HTML4/5) to use hashes, you'd use change the History.js Options within your init

History.options.html4Mode = true 

However, you may also want to consider using the $.address functionality from jQuery which can append any new URL you want with a hash.

Also within the $.address method, you could also determine where to redirect the user based on their init URL if they were accessing the site for the first time: Say, have a user access a URL with say http://www.site.com/#/about.php

you could then have a function which listens to any changes to any changes based on the URL changes

$.address.change(fn)

REF: http://www.asual.com/jquery/address/docs/

UPDATE

One thing I've discovered that may apply here is that if you have a click event handler which behaves by pushing a new state, even if you are currently on that same page, History js will append the same url to the end of the existing URL with a hash

e.g. If on About Page (and your state is "about") and you click the about link - your URL will change from http://www.site.com/about
to
http://www.site.com/about#/about

To save yourself the hassle, have an if statement on that button that checks your History State for "about" and if not, pushState "About"

e.g.

$('.about.btn').on('click', function(e){
  if(History.getState().data.State != "About") {
    e.preventDefault();
    History.pushState({"State": "About"}, null, "/about"); 
  }
})
Ishmaelite answered 12/2, 2014 at 5:0 Comment(4)
But how do you get a url like: http://www.site.com/#/about.php as mine are like: http://www.site.com/#about.php The docs show it as the former but it's the latter for me.Sherbrooke
Also where in my code does that html4mode go? As I can't get it to work for mine.Sherbrooke
REF Comment 2: Where to put html4mode Sorry but I haven't been able to test the html4Mode yet (though I've tried it within my console terminal) - I believe you can init the html4Mode from your document.ready() I'm not confident in saying that if you brought that declaration out of the document ready, that the option will still work.Ishmaelite
REF Comment 1: how to add "/" to your hash If you add History.pushState(obj, titleString, "/"+about.php); This should work in your favourIshmaelite

© 2022 - 2024 — McMap. All rights reserved.