Search code examples
javascriptjqueryhistory.jshtml5-history

Can't figure out History JS


I am trying to implement a navigation to my ajax controlled site, and I am encountering some strange errors.

I am using History JS, the HTML5 only version.

This is how I initialize it:

function initializeHistory() {

    var History = window.History;
    if ( !History.enabled ) {
        console.log("Not enabled!");
        return false;
    }

    // Changing the main page state to -1.
    History.replaceState({id:-1}, baseTitle, baseUrl);

    // Bind to StateChange Event
    History.Adapter.bind(window,'statechange',function(){
        var State = History.getState();
        console.log(History.savedStates);
        if (historyData.manualStateChange)
        {
            if (State.data.id=='-1') alert('History start');
            historyData.allowHistoryPushPop=false;
            var gotoState=historyData.data[State.data.id];
            var currentState=historyData.currentNavigation;

            /* Some code here to revert to the previous state */

            historyData.allowHistoryPushPop=true;
      }

      History.log(State.data, State.title, State.url);
   });
};

I am using a global object, named historyData, in which I store the following things:

var historyData={
    data:                   new Array(), //an array which contains objects that refer to the data that needs to be shown, when back or forward button is pushed
    manualStateChange:      true, //using this to figure out if the back or forward button was pressed in the browser, or if I am adding or removing a state from History programmatically
    allowHistoryPushPop:    true, //using this to prevent history from being changed in certain situations
    currentNavigation:      {
        page:   'dashboard',
        pageid: null,
        module: null,
        moduleid: null
    }, // stores the current object from the historyData.data array
    status: true // boolean that enables or disables History on my page
}

Whenever I click on a link in my page, a function, called navigation fires, which changes the History's state, and eventually runs a chain of functions to display the page which was asked for by the user. The relevant parts from the navigation function are as follows:

function navigation(gotofunc, navData) {
    if ((historyData.allowHistoryPushPop) && (historyData.status))
    {
        if (navData['urlData']==null) // if this is null, then the title and the url for the asked page, will be returned by the server, after an ajax call, so we set it to the current url and current title
        {
            var curState=History.getState();
            urlData={
                title:  curState.title,
                url:    curState.url
            };
        } else {
            urlData=navData['urlData'];
            if (!urlData['title']) urlData['title']=curState.title;
            if (!urlData['url']) urlData['url']=curState.url;
        }
        navData['parameters']=new Array();
        if (arguments.length>2) for (i=2;i<arguments.length ;i++) navData['parameters'].push(arguments[i]);
        historyData.manualStateChange=false; // we are making a programmatic change, so we don't want the binded 'statechange' to fire
        historyData.data.push(navData); // store the history data in our own array
        History.pushState({id:historyData.data.length-1}, urlData['title'], urlData['url']); // push the History state, and set it's id to point to our newly added array element
        historyData.manualStateChange=true; // re-enable the manual state change
    }
}

If I don't know up front what the URL will be after I fetch the data via ajax, my Ajax call, replaces the current state with the correct data, this way:

if ((dataArray['navDat']) && (historyData.status))
        {
            historyData.manualStateChange=false;
            var State = History.getState();
            History.replaceState(State.data, dataArray['navDat']['title'], dataArray['navDat']['url']);
            historyData.manualStateChange=true;
        }

This works fine for the most part. If I navigate forward a few pages, and then go backwards, everything works greatly, if I then go forward once again(all by using the browsers back and forward button), it works greatly. There is only one exception: if I load the page, load a subpage, then try to click on the back button, this line never fires:

   if (State.data.id=='-1') alert('History start');

It basicaly won't figure out that I arrived back at the front page, when I only navigate one page forward.

The other strange thing is the following(perhaps this is what's causing my original problem also): I tried fetching the savedStates of the History object, to see what is going on, and strangely, when I use the replaceState event, it adds a new state in savedStates. One of the objects that is added, is with the correct data id, the other one is with the previous data id.

What could be causing the problem, is there an error in my script somewhere? Or is this completly normal? (the part of adding multiple objects to History.savedStates after replaceState)

Thanks for the help in advance!


Solution

  • If I replace the url, or the title of the page with the first replaceState, the program realizes when I return to the front page, I dunno why, but till then this is the best solution I can figure.