Skip to content

hash 在网页中的作用以及如何通过 hash 实现页面导航与返回的功能

前言

背景

在某万家焕乡 h5 项目中,在 a 页面中点击打开 b 页面后,客户希望通过安卓手机自带的右滑操作返回 a 页面,在安卓设备中,是通过屏幕滑动返回,而 iOS 中是通过网页底部导航栏返回, 讨论采用监听 hash 改变的方式来实现页面导航与返回的功能。

hash

1. # 的含义

代表网页中的一个位置。其右侧的字符,就是该位置的标识符。

比如 http://www.example.com/index.html#print 就代表网页 index.html 中 print 锚点位置。 浏览器读取这个 url 后,会自动将视口滚动至 print 位置。

为网页位置指定标识符, 有两个方法:

  • 使用锚点:比如 <a name='print'></a>
  • 使用 id 属性:比如 <div id='print'></div>

2. http 请求不包括 #

# 是用来指导浏览器动作的,对于服务器端完全无用。所以在设计时,hash 不会被 http 请求发送到服务器。

比如访问 http://www.example.com/index.html#print , 浏览器实际发出的请求是这样的:

GET / index.html HTTP / 1.1
Host: www.example.com

3. # 后的字符

在第一个 # 后面出现的任何字符,都会被浏览器解读为位置标识符

这意味着,这些字符都不会被发送到服务器,比如这段 url 的原意是指定一个颜色值:http://www.example.com/?color=#fff ,但是浏览器实际发出的请求是:

GET / ?color =  HTTP / 1.1
Host: www.example.com

可以看到,"#fff" 被省略了,只有将 # 转码为 %23,浏览器才会将其作为实义字符处理,也就是说,上面的网址应该被写成:http://example.com/?color=%23fff

4. 改变 # 不触发网页重载

单单改变 # 后的部分,浏览器只会滚动到相应位置,不会重新加载网页

比如:从 http://xxx/a.html#location1 => http://xxx/a.html#location2 ,浏览器不会重新向服务器请求 a.html

5. 改变 # 会改变浏览器的访问历史

每一次改变 # 后的部分,都会在浏览器的访问历史中增加一个记录 ( ie6ie7 不成立),使用"后退"按钮,就可以回到上一个位置。

6. window.location.hash 可以读取到 #

window.location.hash 这个属性可读写

  • 读取时:可以用来判断网页状态是否改变
  • 写入时:则会在不重载网页的前提下,创造一条访问历史记录 ( ie6ie7 不成立)

7. onhashchange 事件

HTML5 新增的事件,当 # 值发生变化时,就会触发这个事件。 使用方式有三种:

  • window.onhashchange = func
  • <body onhashchange='func'></body>
  • window.addEventListener('onhashchange', func, false)

对于不支持 onhashchange 的浏览器,可以用 setInterval 监控 location.hash 的变化。

解决方案

所以我们在点击打开 b 页面时,先通过 window.location.hash = '#pageId', 给浏览器增加一条历史记录,再在 b 页面 初始化时,绑定监听器, window.addEventListenetr('hashchange', this.hashChange) 当用户在 b 页面右滑返回操作时,会触发 hashChange 事件, 这时关闭 b 页面,打开 a 页面,即可。

Released under the MIT License.