如何替换位置哈希并仅保留最后的历史条目?

发布于 2025-01-04 03:09:14 字数 675 浏览 0 评论 0原文

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

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

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

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

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

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

I'm using the jQuery BBQ plug-in to track the users progress through the page. However, I only want to create 1 additional entry in the user's history, not one for every hash change.

I've tried the jQuery.bbq.pushState and merge_mode methods, without success: New history entries are still added:

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

I have also tried location.replace(), but that doesn't work for Safari 5.1.2.

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

What's the cross-browser solution to modify the hash, without adding too much entries to the history?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

π浅易 2025-01-11 03:09:14

首先,我展示了函数 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(); // 返回历史记录
    2. 然后,设置 location.hash 属性。如果我们在上一步中返回历史记录,历史记录条目将被覆盖。

    后备(最后)方法可能并不总是取代历史记录:
    location.hash == hash 时,以下任一条件为 true:

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

    因此,为了安全,当哈希值等于保存的原始哈希值时,我们从不卸载页面。

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

First, I show the definition of function replaceHash, which accepts only one argument: The new location hash. A detailed explanation of the logic can be found at the bottom of the answer.

Code:

// 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');

Function logic

  • When history.replaceState is supported, the function will always replace the current hash, without any side effects.
  • Otherwise, a reference (hash) to the very first location.hash property is created, and the following function is defined:

    1. If location.hash != hash, then we know for sure that the history's state is at least past the first page view. We can safely go back in the history, without unloading the page. history.back(); // Go back in the history.
    2. Then, set the location.hash property. If we went back in the history in the previous step, the history entry is overwritten.

    The fallback (last) method may not always replace the history:
    When location.hash == hash, either of the following is true:

    1. The hash hasn't changed yet, so it makes no sense to go back to the previous page.
    2. It's possible that the user navigated backwards, to the original page's state. If we use history.back();, the page might be unloaded, which is not desirable.

    So, to be safe, we never unload the page when the hash is equal to the saved original hash.

    Note: It is important to run this code before a hash change. When the hash has already been changed, the script is not reliable any more. The user could have navigated to the very first hash state, which is not equal to the saved hash. Consequently, history.back() unloads the page.

香橙ぽ 2025-01-11 03:09:14

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

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

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

You could use the replace-method from window.location, without the second newSubStr-argument. This works in all known browsers, even oldIE:

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

Note, that if there's a valid element (as per spec) in the document, the page will jump/scroll to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文