【问题标题】:browser back and forward button does not invoke callback method with statechange event of history.js浏览器后退和前进按钮不会调用带有 history.js 的 statechange 事件的回调方法
【发布时间】:2013-04-16 08:44:39
【问题描述】:

我用过(https://github.com/browserstate/history.js),有一段这样的代码

History.Adapter.bind(window, 'statechange', function() { 
    var State = History.getState();
    alert('Inside History.Adapter.bind: ' + State.data.myData);
});

function manageHistory(url, data, uniqueId){
    var History = window.History;
    if ( !History.enabled ) { return false; }        
    History.replaceState({myData: data}, null, '?stateHistory=' + uniqueId);
}

如果我在我的 ajax 调用之后调用 manageHistory(),那么 History.Adapter.bind 回调方法会被正确调用。但是,如果我向后单击浏览器,然后单击前进按钮,导致页面导航从 B 到 A,然后 A 返回到 B,则不会调用 History.Adapter.bind 内的回调方法。这发生在 chrome 和 IE9 上。任何人都知道如何解决此问题,我需要在单击浏览器后退然后前进后获取State,以更新我的 DOM。请帮忙

注意:我为 html4 浏览器 IE9

使用版本 1.7.1 jquery.history.js

更新(2013 年 5 月 3 日):多谈谈我的要求

对不起,我正忙于其他任务,直到现在我有时才需要查看这个问题。所以@ 987654328@ ajax 调用,我把返回给我的信息,并将其推送到状态。我的要求是:如果我从页面 A 导航到页面 B,然后在页面 B 上,我执行导致 DOM 操作的 ajax 请求的数量(让每个导致 DOM 操作的 ajax 请求称为state)。如果我点击后退按钮,我应该回到页面 A,如果我点击前进按钮,我应该回到页面 B,并保持上一次的状态。

所以我的想法是,oncomplete 在我的 ajax 请求中,我会用我当前的状态替换历史中的最后一个状态(我的 json 对象是我从 ajax 请求返回的 html)。如果我使用推送状态,假设我在页面 B,然后单击一个按钮,我的页面现在更改为 aaa,我推送状态 aaa。然后,如果我单击其他按钮,我的页面现在更改为 bbb,我 pushState bbb。如果我现在单击返回按钮,我仍会在页面 B 上,我的状态为 History.Adapter.bind(window, 'statechange', function() {}) 显示为 aaa,如果我再次单击返回按钮,我将转到页面 A。我不希望这种行为。我希望如果我在状态为bbb 的页面B 上,然后单击返回,我将转到页面A,如果我单击前进,我将转到状态为bbb 的页面B。我希望这更有意义。请帮忙

【问题讨论】:

  • re:您的更新 - 我认为您不想使用历史记录来跟踪页面 B/A 中的“状态更改”。仅将历史记录与您的 URL 更改结合使用。单个 url 中的任何状态更改(即 A 与 B)都应通过另一种机制保存状态(而不是通过 history.replaceState(); ... 这对于像 Backbone 或 Angular 这样的 MV* 库来说非常容易。
  • 查看 jquery-mobile,他们有一种 ajaxy 方式来处理您可能会觉得有用的页面:jquerymobile.com

标签: javascript jquery browser-history pushstate history.js


【解决方案1】:

我看到您正在使用History.replaceState 删除堆栈中的最后一个历史状态并将其替换为参数中给出的状态。

我在我的网站中使用History.pushState,并没有遇到这样的问题,因为此函数不会拉出最后一个状态,而是在其上方添加新状态。它使后退按钮正常工作。

希望对你有帮助。

编辑:使用change of select tag作为事件监听器的例子:

function manageHistory(url, data, uniqueId){
    var History = window.History;
    if ( !History.enabled ) { return false; }        
    History.replaceState({myData: data}, null, '?stateHistory=' + uniqueId);
}

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

    e.preventDefault(); 

    // get url
    // get data
    // get uniqueId

    manageHistory(url, data, uniqueId)


});

History.Adapter.bind(window, 'statechange', function() { 
    var State = History.getState();
    // Launch the ajax call and update DOM using State.data.myData
});

【讨论】:

  • 问题是,根据我的要求,我不能使用 pushState。如果我使用pushState,后退按钮将返回每个ajax请求,但我的要求有点不同,我只想保存最后一个状态
  • 我认为我们对history.js的理解并不相同。我所知道的是,如果您单击按钮 History.Adapter.bind ajax 请求,浏览器按钮将返回到 ajax 请求。如果您只想保存最后一个状态,只需使用 pushState 并且不绑定任何内容。对不起,我对此很陌生。
  • 另外我看到你说:如果我在我的ajax调用之后调用manageHistory()...我认为你应该在将状态推送到堆栈后在managehistory中执行你的ajax调用
  • @ThangPham 您可以使用 pushState ,除非您根据您保存在 State 中的数据明确进行 ajax 调用,否则它不会返回任何 ajax 请求...您能进一步解释您的要求吗?跨度>
  • @NavaRajan:对不起,我正忙于其他任务,直到现在我有时才需要查看这个问题。我在原始问题中更新了我的要求。请看一看。 whiteletters and blankspaces:我也解释了为什么我使用replaceState而不是pushState,请在我的原始问题中查看我的更新
【解决方案2】:

你需要做的如下:

  • 如果您来自的页面是另一个页面(例如,您打开页面 B,而前一页面是页面 A),则执行 pushState
  • 另一方面,如果上一页与您当前所在的页面相同,您只需发送replaceState,将信息替换为有关您当前状态的信息。

你需要在一些变量中手动跟踪上一页

这意味着如果你从 A 转到 B (pushState) 到 B 的新状态 (replaceState),后退按钮(转到 A 的状态信息)和下一步前进(转到 B 的最新状态)。此外,如果您第一次打开 A,您需要使用有关 A 状态的信息执行 replaceState,以便 A 至少具有某种状态(否则它将有一个空数据对象)。

查看我的this answer 可能会很有用,这只是关于您使用pushStates 构建有序历史堆栈的方式。当然不完全是你想要的,但它写得更简单一些,再加上这个答案中的信息,它应该能让你得到你想要的行为。

【讨论】:

  • @Whoever 否决了我...知道为什么真的很高兴,因为我准确地解决了这个问题...
【解决方案3】:

还有,

relpaceState 将始终擦除 B 状态。

pushState 用于 A 和 B 状态。

并使用 replacestate 表示 aaa、bbb、ccc 状态。

function manageHistoryBack(url, data, uniqueId){
    var History = window.History;
    if ( !History.enabled ) { return false; }        
    History.replaceState({myData: data}, null, '?stateHistory=' + uniqueId);


}

function manageHistory(url, data, uniqueId){
    var History = window.History;
    if ( !History.enabled ) { return false; }        
    History.pushState({myData: data}, null, '?stateHistory=' + uniqueId);


}

// Event listenner triggering aaa,bbb,ccc 
$('select.select').change(function(e) {

    e.preventDefault(); 

    // get url
    // get data
    // get uniqueId

    manageHistoryBack(url, data, uniqueId)


});

// Event listenner triggering A, B
$('select.select').change(function(e) {

    e.preventDefault(); 

    // get url
    // get data
    // get uniqueId

    manageHistory(url, data, uniqueId)


});


History.Adapter.bind(window, 'statechange', function() { 
    var State = History.getState();
    // Launch the ajax call and update DOM using State.data.myData 
});

祝你好运

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-19
    • 2013-07-31
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 2014-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多