如何区分浏览器后退和用户手动更改位置哈希

时间:2016-02-19 09:18:32

标签: javascript browser hash back-button browser-history

问题

鉴于从/page.html#B/page.html#A的导航,有没有办法区分用户:

  1. 点击浏览器'返回'按钮,和
  2. 手动将网址更改回'#A'
  3. 背景/背景

    我正在构建一个网络应用,其中一个页面在多个内容幻灯片之间转换,每个内容都由特定的位置哈希标识,例如'#B'/page.html#A

    例如,当用户使用幻灯片&#39; A&#39;并选择选项&#39; B&#39;时,位置会从/page.html#B更改为location.hash==#B。< / p>

    转换后,back()location.hash==#A(通过JS或浏览器按钮)会将用户返回/page.html#B

    但是,没有什么可以阻止用户手动更改URL栏中的哈希值。在这种情况下,浏览器会认为这是向前导航,在后面的历史记录中插入#A。也就是说,导航历史记录为#B&gt; #A&gt; #B然后点击返回即可将用户转到go(N)

    我需要区分这两种情况,以便当我知道用户手动更新了url哈希时,我可以触发popstate来同步浏览器的后退/下一状态。

    到目前为止的尝试

    1)HTML5 .onhashchange事件:
    我原本希望html5 popstate事件(https://developer.mozilla.org/en-US/docs/Web/Events/popstate)只会在案例#1中被触发,但我可以确认它在两种情况下都会触发。

    2)浏览器hashChange()事件
    我可以确认,如果存在,则在两种情况下都会触发该事件

    3)jQuery mobile {{1}} 我确认在两种情况下都被解雇了

    4)阅读浏览器导航历史
    我的下一个想法是维护一个散列历史的JS数组,并比较新散列和浏览器历史是否与JS数组匹配,但出于安全原因,JS无法读取浏览器位置历史记录。

    思想

    我知道如果我调用window.history.forward(),并且没有页面存在,则没有任何反应。我正在考虑一个散列历史的JS数组,调用forward(),检查新的location.hash(现在安全性允许它),与JS数组比较,然后调用go(N)来同步浏览器back / next州。但它有点乱。

2 个答案:

答案 0 :(得分:0)

由于javascript中没有后退按钮事件,我建议您最好在页面上创建自己的后退按钮

请注意:How to Detect Browser Back Button event - Cross Browser

答案 1 :(得分:0)

是的,您可以区分:

  1. 点击back() / forward()浏览器按钮和
  2. 手动修改浏览器网址栏中的location.hash
  3. 也可以同时使用页面内HTML元素导航。

    的问题:

    1. 浏览器back()forward()go()来电不会立即更新location.hash。需要通过setTimeout()等待〜10ms才能让浏览器完成导航并更新location
    2. 解决方案(伪代码):

      • 维护一个backward_history_hashes数组(注意'向后'意味着逻辑上,而不是暂时的)
      • 维持current_location.hash
      • 的值
      • 维护一个forward_history_hashes
      • 数组
      • 维护in-page导航的布尔标记,默认为FALSE
      • 维护布尔标志是否为ignore_hash_change
      • 创建setTimeout()监视器以检查location.hash更改

      在每种情况下,历史数组都是location.hash es

      的简单字符串数组

      on_in_page_navigation()

      • 设置in_page_flag = true
      • 通过back()forward()go(N)
      • 触发浏览器导航
      • 设置in_page_flag = false

      on_location_hash_change()

      • 设置ignore_hash_change = true
      • if(! in_page_flagrewrite_browser_history()
      • 显示与新location.hash
      • 对应的内容
      • 设置ignore_hash_change = false

      rewrite_browser_history()

      • 假设它是一个手动URL编辑,并使用JS历史数组来触发back()forward()调用以生成所需的浏览器历史记录
      • 执行go(N)到期望的location.hash以将浏览器历史记录与JS历史数组同步