您可以在不影响历史记录的情况下使用哈希导航吗?


99

恐怕这是不可能的,但是有没有一种方法可以更改URL的哈希值而又不会在浏览器的历史记录中留下任何条目并且无需重新加载?还是等效?

就细节而言,我正在按照以下方式开发一些基本的哈希导航:

//hash nav -- works with js-tabs
var getHash = window.location.hash;
var hashPref = "tab-";
function useHash(newHash) {
    //set js-tab according to hash
    newHash = newHash.replace('#'+hashPref, '');
    $("#tabs li a[href='"+ newHash +"']").click();
}
function setHash(newHash) {
    //set hash according to js-tab
    window.location.hash = hashPref + newHash;

    //THIS IS WHERE I would like to REPLACE the location.hash
    //without a history entry

}
    // ... a lot of irrelavent tabs js and then....

    //make tabs work
    $("#tabs.js-tabs a").live("click", function() {
        var showMe = $(this).attr("href");
        $(showMe).show();
        setHash(showMe);
        return false;
    });
    //hash nav on ready .. if hash exists, execute
    if ( getHash ){
        useHash(getHash);
    }

显然,使用jQuery。这个想法是,在这种特定情况下, 1)通过堆积不必要的引用来使用户回头查看每个选项卡更改可以有效地“破坏后退按钮”,以及2)如果他们单击“刷新” 则不保留他们当前位于哪个选项卡烦人。


如果不想保留历史记录,为什么还要更改哈希?:|
Ionuț Staicu 2010年

9
因为在刷新时最好向用户显示他们所在的选项卡,但是由于他们可能在选项卡之间来回切换,因此不必要地增加了他们的历史记录,从而使后退按钮实际上没什么用处。但是,这只是一个示例-可能在任何时候您都需要保存一个临时状态,但又不想依赖cookie或用它们填充用户的临时文件。刷新时,js内容就如您所愿-您尚未离开页面,它也不是跳转点或伪页面,因此历史记录条目只能干扰标准导航。

Answers:


94

location.replace("#hash_value_here");在我发现它无法在IOS Chrome上运行之前,对我来说效果很好。在这种情况下,请使用:

history.replaceState(undefined, undefined, "#hash_value")

history.replaceState()的操作与history.pushState()完全相同,不同之处在于replaceState()会修改当前历史记录条目,而不是创建一个新的条目。

切记保留#网址的或最后一部分将被更改。


3
完全是现代浏览器的必经之路;请注意部分支持会话历史记录管理。
马特

我对如何使用它感到困惑。我应该仍然使用window.location.hash = 'my-hash';其后history.replaceState(undefined, undefined, "#my-hash")吗?
Bram Vanroy

2
@BramVanroy不,使用后者就足够了。
露西亚

2
除非您使用:target选择器...,否则历史记录功能是无用的,因为该规范的一部分(与历史记录操作的CSS交互)当前尚未定义,并且样式不会在大多数/所有浏览器替换的历史记录上重新计算。
变身

@Luxiyalu,有history.replaceState什么不同location.replace
佩里耶

99
location.replace("#hash_value_here"); 

以上似乎可以满足您的要求。


4
就是这个。如果您有uri段,则location.replace(window.location +“ #hash”)将保留它们。
2012年

7
其次,这种方法更加清洁,希望将其标记为正确答案。
joeellis 2012年

14
window.location.replace(('' + window.location).split('#')[0] + '#' + hash);只是更新哈希值
johnstorm

1
我正在Windows 8下的Chrome 30中对其进行测试,如果我转到Chrome历史记录并在测试URL下选择“来自此站点的更多信息”,则可以看到此方法添加的所有哈希值。
2013年

1
当心location.replace('#hash_value_here')仅更改哈希片段,而不更改路径,因此它不会触发页面加载...。除非文档包含基本标记: <base href ="http://example.com/" /> 如果它确实包含基本标记,那么当您仅使用带头的替换方法时"#hash_value_here",实际上就像您说了“ location.replace(' example.com/#hash_value_here')”。当您在此处阅读时,这似乎很明显,但是当您在具有路径片段的页面上并且没有意识到设置了基准时,这是一个陷阱。
泰勒·卡斯滕

6

编辑:已经有几年了,浏览器也在不断发展。

@Luxiyalu的答案是要走的路

- 旧答案 -

我也认为这是不可能的(目前)。但是,如果您不打算使用哈希值,为什么还要更改它呢?

我相信我们将哈希值用作程序员的主要原因是让用户为我们的页面添加书签,或者将状态保存在浏览器历史记录中。如果您不想执行任何操作,则只需将状态保存在变量中,然后从那里开始工作。

我认为使用散列的原因是要使用我们无法控制的值。如果不需要它,则可能意味着您可以控制所有内容,因此只需将状态存储在变量中并使用它即可。(我喜欢重复自己)

我希望这能够帮到你。也许有一个更简单的解决方案来解决您的问题。

更新: 怎么样:

  1. 设置第一个哈希,并确保将其保存在浏览器历史记录中。
  2. 选择一个新选项卡后,请执行window.history.back(1),这将使历史记录从您的第一个init哈希返回。
  3. 现在,您设置了新的哈希,因此制表符将仅在历史记录中输入一个。

您可能必须使用一些标志,以了解是否可以通过返回来“删除”当前条目,或者只是跳过第一步。并且请确保在您强制执行时,“哈希”的加载方法没有执行history.back


很可能我缺少一些基本的东西(精疲力尽是一个很好的借口,我会同意的),但是您是在说我可以设置一个变量来在重新加载时保留其更改后的值吗?除了饼干?(以某种方式,Cookie看起来过于矫kill。)也许这还不清楚。我将使用哈希值-尤其是在重新加载时。感谢您的回应!

为了澄清我的澄清:如果用户点击重载。这就是哈希的用途。我仍在尝试避免在正常使用时重新加载(更改/单击标签)。

好的,所以您将在重新加载后使用一些值来获取信息。不幸的是,哈希值将由某些浏览器的历史记录选择。不好意思地说,但是从我的经验来看,cookies是最好的选择。如果您希望浏览器历史记录无法检测到某些内容,但希望在重新加载后保留这些内容,那么可以使用Cookie。如果用户单击链接,则可以将链接设置为查询(?mystate=greatness),即使它不需要是ajax,也可以保存信息以供javascript在初始化请求时读取。
guzart 2010年

是的,哈希值用于在重新加载后保存用户的信息,但是您遇到的问题是,某些浏览器会保存历史记录中的这些更改,这只是它们的工作方式... :(
guzart 2010年

是的,认为您是对的。呃,好吧。(是否希望通过其他方法或某些方法证明爱是错误的。)

-1

您始终可以创建一个事件侦听器,以捕获超链接上的单击事件,并在回调函数中放置e.preventDefault(),这应防止浏览器将其插入到历史记录中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.