我使用jQuery BBQ插件来跟踪用户在页面中的进度。然而,我只想在用户的历史记录中创建一个额外的条目,而不是为每个哈希更改创建一个条目。
我尝试过jQuery.bbq.pushState
和merge_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
),并定义以下函数:- 如果是
location.hash != hash
,那么我们确信历史的状态至少超过了第一个页面视图。我们可以安全地回到历史,而无需卸载页面history.back(); // Go back in the history
- 然后,设置
location.hash
属性。如果我们在上一步中返回历史记录,则历史记录条目将被覆盖
回退(最后)方法可能并不总是替换历史记录:
当location.hash == hash
时,以下任一项为真:- 散列还没有改变,所以返回到上一页是没有意义的
- 用户可能向后导航到原始页面的状态。如果我们使用
history.back();
,页面可能会被卸载,这是不可取的
因此,为了安全,当哈希等于保存的原始哈希时,我们从不卸载页面注意:在更改哈希之前运行此代码非常重要。当散列已经更改时,脚本就不再可靠了。用户本可以导航到第一个散列状态,该散列状态不等于保存的
hash
。因此,history.back()
卸载页面。- 如果是
您可以使用window.location
中的replace
-方法,而不需要第二个newSubStr
-参数。这适用于所有已知的浏览器,甚至旧的IE:
function replaceHash(hash) {
return window.location.replace(
'#' + hash.replace(/^#/, '')
);
}
注意,如果文档中有一个有效的元素(根据规范),页面将跳转/滚动到它。