Search code examples
htmlbrowser-historypushstatehistory.jshtml5-history

History.js vs. window.history for HTML5-only mode


Does History.js offer any substantial advantages over HTML5's window.history nowadays? We're not interested in supporting/falling back to the HTML4 hashbang URLs.

History.js doesn't support anchors in pushState(), while window.history does. We need this feature so if there are no big reasons to use History.js instead of the native window.history in HTML5-only mode, we'd rather go for the latter.


Solution

  • Yes - on their website they say:

    Provide a cross-compatible experience for all HTML5 Browsers (they all implement the HTML5 >History API a little bit differently causing different behaviours and sometimes bugs - >History.js fixes this ensuring the experience is as expected / the same / great throughout >the HTML5 browsers)

    Those differences are small, and googling wasn't enough to find them - I had to look in the source code - it seems that the main one is fixing the HTML5 functionality in safari. There are two problems with the safari implementation - one is that history.back fails to return to a hash state set by location.hash which is susequently replaced by history.replaceState.

    The second is that when busy safari will fail to apply state changes.

    Relevant History.js source code:

        History.bugs = {
            /**
             * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call
             * https://bugs.webkit.org/show_bug.cgi?id=56249
             */
            setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)),
    
            /**
             * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions
             * https://bugs.webkit.org/show_bug.cgi?id=42940
             */
            safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)),
    

    So I guess your decision comes down to whether you care about Safari 5 and Safari IOS 4.