18

我正在使用jQuery BBQ 插件来跟踪用户在页面中的进度。但是,我只想在用户历史记录中创建 1 个附加条目,而不是为每个哈希更改创建一个。

我已经尝试了jQuery.bbq.pushStateandmerge_mode方法,但没有成功:仍然添加了新的历史条目:

jQuery.bbq.pushState({ sort: encodeURIComponent(sort) });

我也尝试过location.replace(),但这不适用于 Safari 5.1.2。

location.replace('#' + encodeURIComponent(sort))

修改哈希的跨浏览器解决方案是什么,而不在历史记录中添加太多条目?

4

2 回答 2

38

首先,我展示了 function 的定义,replaceHash它只接受一个参数:新的位置哈希。可以在答案的底部找到对逻辑的详细解释。

代码:

// Should be executed BEFORE any hash change has occurred.
(function(namespace) { // Closure to protect local variable "var hash"
    if ('replaceState' in history) { // Yay, supported!
        namespace.replaceHash = function(newhash) {
            if ((''+newhash).charAt(0) !== '#') newhash = '#' + newhash;
            history.replaceState('', '', newhash);
        }
    } else {
        var hash = location.hash;
        namespace.replaceHash = function(newhash) {
            if (location.hash !== hash) history.back();
            location.hash = newhash;
        };
    }
})(window);
// This function can be namespaced. In this example, we define it on window:
window.replaceHash('Newhashvariable');

功能逻辑

  • 支持时history.replaceState,该函数将始终替换当前哈希,没有任何副作用。
  • 否则,将创建hash对第一个location.hash属性的引用 ( ),并定义以下函数:

    1. 如果location.hash != hash,那么我们肯定知道历史的状态至少超过了第一个页面视图。我们可以安全地返回历史,而无需卸载页面。history.back(); // Go back in the history.
    2. 然后,设置location.hash属性。如果我们在上一步中返回历史记录,则历史记录条目将被覆盖。


    后备(最后)方法可能并不总是替换历史:
    location.hash == hash,以下任一情况为真:

    1. 哈希还没有改变,所以返回上一页是没有意义的。
    2. 用户可能向后导航到原始页面的状态。如果我们使用history.back();,页面可能会被卸载,这是不可取的。


    所以,为了安全起见,当哈希值等于保存的原始哈希值时,我们永远不会卸载页面。

    注意:在哈希更改之前运行此代码很重要。当哈希值已经改变时,脚本不再可靠。用户可能已经导航到第一个哈希状态,该状态不等于已保存的hash. 因此,history.back()卸载页面。

于 2012-02-14T18:43:56.570 回答
23

您可以使用replace来自的 - 方法window.location,而无需第二个newSubStr- 参数。这适用于所有已知的浏览器,甚至 oldIE:

function replaceHash(hash) {
  return window.location.replace(
    '#' + hash.replace(/^#/, '')
  );
}

请注意,如果文档中有有效元素(根据规范),页面将跳转/滚动到它。

于 2013-06-24T06:15:05.843 回答