你能在不影响历史的情况下使用哈希导航吗?

Posted

技术标签:

【中文标题】你能在不影响历史的情况下使用哈希导航吗?【英文标题】:Can you use hash navigation without affecting history? 【发布时间】:2011-01-19 06:57:40 【问题描述】:

恐怕它可能是impossible,但有没有办法更改 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)不保留他们是哪个选项卡当前在如果他们点击刷新是一个烦恼。

【问题讨论】:

如果您不想跟踪历史记录,为什么要更改哈希? :| 因为在刷新时最好向用户显示他们所在的选项卡,但是由于他们可能在选项卡之间来回翻转,这会使他们的历史记录出现不必要的条目,使返回按钮其实用处不大。不过,这只是一个示例——它可能适用于您需要保存临时状态但又不想依赖 cookie 或用它们填充用户的临时文件的任何时候。刷新时,js内容和你离开的一样——你没有离开页面,也不是跳转点或伪页面,所以历史条目只能干扰标准nav。 【参考方案1】:

location.replace("#hash_value_here"); 对我来说工作得很好,直到我发现它在 ios Chrome 上不起作用。在这种情况下,请使用:

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

history.replaceState() 的操作与 history.pushState() 完全相同,只是 replaceState() 修改当前历史条目而不是创建新条目。

记得保留#,否则url的最后一部分会被改变。

【讨论】:

完全是现代浏览器的必经之路;请注意partial support 会话历史管理。 @BramVanroy 不,使用后者就足够了。 除非你使用 :target 选择器......然后历史函数是无用的,因为规范的那部分(css 与历史操作的交互)目前似乎没有定义,并且样式不会被重新计算大多数/所有浏览器替换历史记录。 请注意:history.replaceState()location.replace() 仍会在 Chrome 历史记录中创建条目,这在某些情况下可能被认为是不可接受的:***.com/questions/26793130/… 注意:有趣的是,history.replaceState(...) 确实不会触发window.onhashchange 事件。 location.replace 确实如此。很奇怪,对吧?【参考方案2】:
location.replace("#hash_value_here"); 

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

【讨论】:

就是这样。如果你有 uri 段,location.replace(window.location + "#hash") 将保留它们。 第二次这个方法,干净多了,希望它被标记为正确答案。 window.location.replace(('' + window.location).split('#')[0] + '#' + hash); 仅更新哈希 我正在 Windows 8 下的 Chrome 30 中对其进行测试,如果我转到 Chrome 历史记录并在我的测试 url 下选择“来自此站点的更多内容”,我可以看到所有添加的哈希方法。 请注意 location.replace('#hash_value_here') 只更改哈希片段而不是路径,因此它不会触发页面加载....除非文档包含基本标记:<base href ="http://example.com/" /> 如果它确实包含一个基本标签,那么当您使用仅带有前导 "#hash_value_here" 的替换方法时,实际上就像您说的是 `location.replace('example.com/#hash_value_here')。当您在此处阅读时,这似乎很明显,但是当您在一个带有路径片段的页面上并且没有意识到 base 已设置时,这是一个问题。【参考方案3】:

编辑:到现在已经有几年了,浏览器也在进化。

@Luxiyalu 的answer 是要走的路

--旧答案--

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

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

我认为使用哈希的原因是使用我们无法控制的值。如果您不需要它,那么这可能意味着您可以控制一切,因此只需将状态存储在变量中并使用它。 (我喜欢重复自己)

我希望这对您有所帮助。也许有更简单的方法可以解决您的问题。

更新: 这个怎么样:

    设置第一个哈希值,并确保它保存在浏览器历史记录中。 选择新标签后,执行window.history.back(1),这将使历史从您的第一个初始化哈希返回。 现在您设置了新的哈希值,因此制表符只会在历史记录中创建一个条目。

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

【讨论】:

很可能我缺少一些基本的东西(精疲力竭是一个很好的借口,我会同意的)但是你是说我可以设置一个变量,在重新加载时保留其更改的值?除了饼干? (不知何故,Cookie 似乎有点矫枉过正……)也许这不是很清楚。我将使用哈希值——尤其是在重新加载时。感谢您的回复! 澄清我的澄清:如果用户点击重新加载。这就是哈希的用途。我仍在尝试避免在正常使用中重新加载(更改/单击选项卡)。 好的,所以您将在重新加载后使用一些值作为信息。不幸的是,哈希值会被某些浏览器的历史记录选中。很抱歉这么说,但从我的经验来看,cookie 是你最好的选择。如果您想要浏览器历史记录未检测到但在重新加载后保留的东西,不幸的是,cookie。如果用户正在单击链接,那么您可以将链接设置为查询 (?mystate=greatness),即使它不需要是 ajax,您也可以保存信息以供 javascript 在初始化请求时读取。 是的,哈希是为了在点击重新加载后保存用户的信息,但对你来说,问题是某些浏览器会将这些更改保存在历史记录中,这就是它们的工作方式...... :( 是的,认为你是对的。呃,好吧。 (希望通过其他方法或其他方法被证明是错误的。)【参考方案4】:

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

【讨论】:

以上是关于你能在不影响历史的情况下使用哈希导航吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不导航到该 url 的情况下推送历史记录条目并更改地址栏 url?

在不影响导航栏的情况下更改 NavigationController 的内容视图宽度

在不损失任何质量的情况下调整图像大小[关闭]

如何在不更改域名服务器的情况下测试 CloudFlare

Git 可以在不丢失历史记录的情况下重组我的文件夹吗?

我可以在不删除最近提交的情况下删除源/主合并历史记录吗?