如何让浏览器返回按钮忽略哈希标签?

11
我有一个网站,用哈希标志来打开/关闭当前页面上的一些选项卡和图层。使用哈希标志的原因是,如果用户通过链接访问另一页,然后返回原始页面,则所有选项卡和图层应该像离开该页面时一样全部打开。
问题在于,当在第一页并使用浏览器的后退按钮时,只有哈希标志发生变化,而用户必须多次点击才能实际返回到上一个“真实”的页面。
可以更改这种行为吗?下面是一个示例工作流程:
所以我正在访问一个页面: start.php > 点击链接 > processing.php > 点击选项卡,哈希标志发生变化 > processing.php#1 > 在页面上单击不同的部分,哈希标志变为 > processing.php#1-2 现在,当我按浏览器的后退按钮时,我想返回到: start.php 而不是 processing.php#1 但是! 当我从以下位置进行导航: processing.php#1-2 > 导航到 > otherpage.php 然后从那里点击后退按钮,我需要返回到: processing.php#1-2 以恢复打开的选项卡和图层。
是否可能?任何帮助都将不胜感激!

据我所知,这是不可能的。也许可以编写一些 hacky 的哈希操作代码, 在哈希值更改时存储历史记录,当浏览器后退时,触发事件一直返回,直到退出页面。那可能比它值得的工作还要多。 - Peter Olson
我建议您直接运行JS事件,而不生成新的哈希标签,因为显然您不再需要它们。 - Blazemonger
我需要它们从example.php#1转到other_page.php,然后返回到example.php#1 <-那就是我需要哈希的地方。 - user991349
查看历史方法 https://developer.mozilla.org/zh-CN/docs/Web/API/Window/history - Alex Turpin
5个回答

10
据我所知,如果没有JavaScript,你无法解决这个问题。片段是URL的一部分,当它改变时,新的URL将被添加到历史记录中。
我建议在想要更改URL而不创建历史记录条目时使用location.replace()。而不是设置window.location.hash,请尝试以下方法:
window.location.replace('#1');

我会留给你选择最佳方式将其集成到您的网站中,但这里提供了一种经过最小测试的选项,用于捕获链接上的点击:
$(window).on('click', 'a', function(e){
    var href = $(e.target).attr('href');
    if (href && href[0] === '#') {
        window.location.replace(e.target.href);
        return false;
    }
});

1
使用 .replace() 修改哈希值,而不创建历史记录条目。 - aknosis
2
@Aknosis 我认为我已经这么说了...不是吗? - s4y
我只是在重申/总结你所说的话。 - aknosis

3

这是浏览器有意为之的行为,也是哈希标签的正确用法。因此,建议您考虑使用哈希标签的JavaScript是否存在问题,并更改为其他存储方法。实际上,您可以只使用全局可用的JavaScript变量来实现该目的,因为不会发生页面重新加载,变量将持久存在。

window.stage = 'start';

// Another stage
window.stage = 'onfire'

当然,您仍需要禁止js元素的点击标准行为。
或者,如果您希望存储阶段,但不希望其可导航,可以考虑在更现代的浏览器上使用本地存储。
编辑:(基于新信息)
您正在尝试做的事情在webdev中是一种极为常见的场景,因为页面并没有保存用户状态/信息。
您想存储有关用户完成了什么、处于过程的哪个阶段的信息。即使他们已经离开了页面。
有一些有限的存储数据的位置:哈希、localStorage、cookies、客户端等。如果我是您页面的用户,我会希望我的数据无论如何都能被存储。
因此,我建议考虑一个更好的位置来存储网页的状态,而不是哈希,哈希通常用于导航。如果他们将通过php登录,只需通过php将其存储到数据库中。如果没有,则将其存储到localStorage(如果有)并回退到cookies,或者只使用cookies。
您的最终导航可能看起来像这样:起始页>处理页>任何其他页>处理页>离开站点>返回处理页。
但每次他们返回处理页时,他们的数据都将以他们离开时的状态存储在那里。
如果出于某种原因必须使用哈希,请参考@Sidnicious的答案,其中有一种方法可以跳过创建历史记录条目的步骤,因此如果您在除更改页面之前的所有阶段都使用它,则您的历史记录将如下所示:起始页>processing.php>processing.php#final>otherpage.php,这可能会减少返回按钮的点击次数。

问题是,还有一个other_page.php。因此,在从example.php#3点击链接转到other_page.php并返回example.php后,哈希更改确实需要出现,以便可以通过example.php#3中的哈希初始化所有元素。这很令人困惑...我知道 :( - user991349
1
嗯,很多都取决于您的规格,但在现代浏览器中使用localStorage可能会解决这个问题。关键在于当您需要可导航性时,即使对于所有那些您不想被导航的阶段,您也应该更改哈希,即使您同时使用本地变量。如果您试图使example.php更改状态并且在某人导航离开example.php并返回时不返回其先前的状态,则应考虑实际存储数据,例如在php中的数据库中。所以,呃,更清楚地说明要求?更好的例子? - Kzqai
几点建议:您的原始帖子不太清楚。将来,我建议跳过示例场景,描述您实际的情况,这将使人们为解决方案提供更恰当的建议。您对工作流程的澄清并没有很好地澄清您要做什么。更好的方法是发布当前正在进行的示例/片段,例如在jsfiddle.net上。我将编辑我的答案,尽我所能完整地分析并提出解决问题的解决方案。 - Kzqai

2

我遇到了与你描述的相同问题。我同意Ivan Ivković的想法。以下是我的代码,它适用于我的情况。我刚接触JS,但希望它有所帮助。

var counter = 0;
window.onhashchange = function() {
    window.history.replaceState({visited: ++counter}, "visited page", 

window.location.search+window.location.hash);
}

window.onpopstate = function(event) {
    if(event.state.visited && counter>event.state.visited) {
    counter -= 2;
    window.history.go(-1*event.state.visited);
    }
    else {
    counter = event.state.visited;
    }
}

0

您可以计算自页面加载以来点击了多少个哈希标记,然后使用该计数与 history.go(-countHashes) 一起返回到您的页面。


0

也许可以使用JavaScript阻止默认行为并跳转到哈希值?

$("a").click(function(event) {
  $("html,body").scrollTop($(this.hash)[0].offsetTop)
  event.preventDefault();
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接