1

I have a <select> tag. On changing the selected item, some <div>s are updated using AJAX via the functions: update_div1, update_div2, update_div3. The code managing this operation is below and working well:

$('select.select-x').change(function(e) {

    e.preventDefault(); 

    var value = $('select.select-x option:selected').val(); 
    var text = $('option:selected').text();

    update_div1(value); 
    update_div2(value);
    update_div3(value);
    manage_history(value,text);

    return false;

});

The problem is in the last function manage_history which is responsable of managing browser history. In this function I am using history.js to push browser states in history stack. As I know after reading many articles on SO about history.js, the actions of back and forward buttons should be inclueded in History.Adapter.bind(). The problem is that the back-forward buttons of the browser are having weird behaviour: They execute the functions inside History.Adapter.bind() many times, exaclty the number of times I already had an onChange event triggerd via <select>.

The code of manage_history is:

function manage_history(str,str2)
{

    var History = window.History;
    if ( !History.enabled ) { return false; }

    var path = 'http://localhost/enc/?p='+str;

    History.pushState({myid:str},str2,path);

    History.Adapter.bind(window,'statechange',function() { 

        var State = History.getState();

        update_div1(State.data.myid); fter
        update_div2(State.data.myid);
        update_div3(State.data.myid);
    }); 
} 

I hope I was clear. Your help is appreciated.

The whole Solution after theBrain contribution:

$('select.select-x').change(function(e) {

    e.preventDefault(); 

    var value = $('select.select-x option:selected').val(); 
    var text = $('option:selected').text();

    manage_history(value,text);

    return false;

});

History.Adapter.bind(window,'statechange',function() { // Note:  Using statechange instead of popstate

        var State = History.getState();

            update_div1(value); 
        update_div2(value);
            update_div3(value);

    }); 

function manage_history(str,str2)
{

    var History = window.History;
    if ( !History.enabled ) { return false; }

    var path = 'http://localhost/enc/?p='+str;

    History.pushState({myid:str},str2,path);

        update_div1(State.data.myid); 
        update_div2(State.data.myid);
            update_div3(State.data.myid);

} 
Adib Aroui
  • 4,981
  • 5
  • 42
  • 94

1 Answers1

2

move the History.Adapter.bind away from the manage_history function. You rebind it every time you call the manage_history function.

TheBrain
  • 5,528
  • 2
  • 25
  • 26
  • Thank you for your feedback to this issue. Will it be appropriate to move the History.Adapter.bind and put it in my $('select.select-x').change(function(e) {} ?? I will test meanwhile and come back here – Adib Aroui Apr 11 '13 at 17:18
  • 1
    @lettersandblankspaces You should only bind it once. so don't put it in functions that are called more than once. But if you really want to do it that way, you can do a $(window).unbind('statechange') just above the `History.Adapter.bind` so it removes the old one – TheBrain Apr 11 '13 at 17:22
  • Perfect TheBrain. You are really now making me feel I understand how the history.js works. – Adib Aroui Apr 11 '13 at 17:30
  • when I click browser.back and then browser.forward, callback `History.Adapter.bind(window,'statechange',function() {...})` does not get called, this happen on both chrome and IE9. If I switch to `popstate` then chrome will invoke the `bind callback` but not IE9. Any idea why, TheBrain? – Thang Pham Apr 23 '13 at 07:55
  • I made a separate question here: http://stackoverflow.com/questions/16164210/ie9-browser-back-and-forward-button-does-not-work-correctly-with-statechange-eve – Thang Pham Apr 23 '13 at 08:13