如何区分浏览器返回和用户手动更改位置哈希
How distinguish between browser back and user manually changing location hash
问题
给定从 /page.html#A
到 /page.html#B
的导航,有没有办法区分用户:
- 单击浏览器的 'back' 按钮,然后
- 手动将 url 改回
/page.html#A
?
背景/背景
我正在构建一个 Web 应用程序,其中单个页面在多张内容幻灯片之间转换,每张幻灯片都由特定的位置哈希值标识,例如 '#A'
、'#B'
.
例如,当用户在幻灯片 'A' 上并选择选项 'B' 时,位置从 /page.html#A
变为 /page.html#B
。
转换后,location.hash==#B
和 back()
(通过 JS 或浏览器按钮)将 return 用户 location.hash==#A
。
但是,没有什么可以阻止用户手动更改 URL 栏中的散列。在这种情况下,浏览器会认为这是向前导航,在向后历史记录中插入 /page.html#B
。也就是说,导航历史记录将是 #A
> #B
> #A
并且现在点击返回会将用户带到 #B
.
我需要区分这两种情况,以便当我知道用户手动更新了 url 哈希时,我可以触发 go(N)
来同步浏览器 back/next 状态。
到目前为止的尝试次数
1) HTML5 popstate
事件:
我曾希望 html5 popstate 事件 ( https://developer.mozilla.org/en-US/docs/Web/Events/popstate ) 只会在案例 #1 中触发,但我可以确认它在两种情况下都会触发。
2) 浏览器 .onhashchange
事件
我可以确认如果存在,事件在两种情况下都会被触发
3) jQuery 手机 hashChange()
我可以确认在这两种情况下都被解雇了
4) 读取浏览器导航历史
我接下来的想法是维护一个哈希历史的JS数组,并比较新的哈希和浏览器历史是否与JS数组匹配,但是出于安全原因,JS无法读取浏览器位置历史。
想法
我知道如果我调用 window.history.forward() 并且没有页面存在,则什么也不会发生。我在想一个哈希历史的 JS 数组,调用 forward(),检查新的 location.hash(现在安全允许),与 JS 数组进行比较,然后调用 go(N) 来同步浏览器 back/next 状态。但是有点乱。
由于 javascript 中没有后退按钮事件,我建议最好的办法是在您的页面上创建您自己的后退按钮
看:How to Detect Browser Back Button event - Cross Browser
是的,你可以区分:
- 单击
back()
/forward()
浏览器按钮,然后
- 在浏览器中手动编辑
location.hash
栏URL
也可以将两者与页内 HTML 元素导航一起使用。
问题:
- 浏览器
back()
、forward()
和 go()
调用不会立即更新 location.hash
。需要通过 setTimeout()
等待 ~10ms 让浏览器完成导航和更新 location
.
解决方案(伪代码):
- 维护一个
backward_history_hashes
的数组(注意'backwards'是逻辑上的,不是时间上的)
- 保持值
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_flag
)rewrite_browser_history()
- 显示新内容对应
location.hash
- 设置
ignore_hash_change
= false
rewrite_browser_history()
- 假设它是手动 URL 编辑,并使用 JS 历史数组触发
back()
和 forward()
调用以生成所需的浏览器历史记录
- 执行
go(N)
到所需的location.hash
以同步浏览器历史与JS历史数组
问题
给定从 /page.html#A
到 /page.html#B
的导航,有没有办法区分用户:
- 单击浏览器的 'back' 按钮,然后
- 手动将 url 改回
/page.html#A
?
背景/背景
我正在构建一个 Web 应用程序,其中单个页面在多张内容幻灯片之间转换,每张幻灯片都由特定的位置哈希值标识,例如 '#A'
、'#B'
.
例如,当用户在幻灯片 'A' 上并选择选项 'B' 时,位置从 /page.html#A
变为 /page.html#B
。
转换后,location.hash==#B
和 back()
(通过 JS 或浏览器按钮)将 return 用户 location.hash==#A
。
但是,没有什么可以阻止用户手动更改 URL 栏中的散列。在这种情况下,浏览器会认为这是向前导航,在向后历史记录中插入 /page.html#B
。也就是说,导航历史记录将是 #A
> #B
> #A
并且现在点击返回会将用户带到 #B
.
我需要区分这两种情况,以便当我知道用户手动更新了 url 哈希时,我可以触发 go(N)
来同步浏览器 back/next 状态。
到目前为止的尝试次数
1) HTML5 popstate
事件:
我曾希望 html5 popstate 事件 ( https://developer.mozilla.org/en-US/docs/Web/Events/popstate ) 只会在案例 #1 中触发,但我可以确认它在两种情况下都会触发。
2) 浏览器 .onhashchange
事件
我可以确认如果存在,事件在两种情况下都会被触发
3) jQuery 手机 hashChange()
我可以确认在这两种情况下都被解雇了
4) 读取浏览器导航历史
我接下来的想法是维护一个哈希历史的JS数组,并比较新的哈希和浏览器历史是否与JS数组匹配,但是出于安全原因,JS无法读取浏览器位置历史。
想法
我知道如果我调用 window.history.forward() 并且没有页面存在,则什么也不会发生。我在想一个哈希历史的 JS 数组,调用 forward(),检查新的 location.hash(现在安全允许),与 JS 数组进行比较,然后调用 go(N) 来同步浏览器 back/next 状态。但是有点乱。
由于 javascript 中没有后退按钮事件,我建议最好的办法是在您的页面上创建您自己的后退按钮
看:How to Detect Browser Back Button event - Cross Browser
是的,你可以区分:
- 单击
back()
/forward()
浏览器按钮,然后 - 在浏览器中手动编辑
location.hash
栏URL
也可以将两者与页内 HTML 元素导航一起使用。
问题:
- 浏览器
back()
、forward()
和go()
调用不会立即更新location.hash
。需要通过setTimeout()
等待 ~10ms 让浏览器完成导航和更新location
.
解决方案(伪代码):
- 维护一个
backward_history_hashes
的数组(注意'backwards'是逻辑上的,不是时间上的) - 保持值
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_flag
)rewrite_browser_history()
- 显示新内容对应
location.hash
- 设置
ignore_hash_change
=false
rewrite_browser_history()
- 假设它是手动 URL 编辑,并使用 JS 历史数组触发
back()
和forward()
调用以生成所需的浏览器历史记录 - 执行
go(N)
到所需的location.hash
以同步浏览器历史与JS历史数组