如何替换位置哈希并只保留最后一个历史记录条目



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

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

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

我也尝试过location.replace(),但这对Safari5.1.2不起作用。

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

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

首先,我展示了函数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时,该函数将始终替换当前哈希,不会产生任何副作用
  • 否则,将创建对第一个location.hash属性的引用(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()卸载页面。

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

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

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

相关内容

  • 没有找到相关文章

最新更新