从了解Hash和Html5 History 到简单实现路由

原创 Lin_Grady 教程 框架/库 276阅读 26 天前 举报

Hash

hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分),在页面中的hash有多种功能意义:

锚点

浏览器读取到hash之后自动滚动到该对应元素所在位置的可视区域内

不附加在请求上

意味着它不管怎么变化都不会影响请求URL,即它只针对浏览器的.

注意: 有种情况是你会在URL上带#符号,但是你本意不是作为hash使用的,例如回调地址或者传参之类,这时候浏览器只会当做hash处理,所以需要先转码.

改变访问历史但不会触发页面刷新

这个大家都知道,尽管它不会跳转也不会刷新,但是你能通过点击浏览器前进后退发现它也会被添加去访问历史记录里.(低版本IE不考虑)

缺点

  • 搜索引擎不友好
  • 难以追踪用户行为

思路

当URL的片段标识符更改时,将触发hashchange事件 (跟在#符号后面的URL部分,包括#符号),然后根据hash值做些路由跳转处理的操作.具体参数可以访问location查看

最基本的路由实现方法监听事件根据location.hash判断界面

具体代码可以查看hash_demo.html

History

DOM window 对象通过 history 对象提供了对浏览器的会话历史的访问。它暴露了很多有用的方法和属性,允许你在用户浏览历史中向前和向后跳转

向前和向后跳转

跳转到 history 中指定的一个点

你可以用 go() 方法载入到会话历史中的某一特定页面, 通过与当前页面相对位置来标志 (当前页面的相对位置标志为0).

添加历史记录中的条目

不会立即加载页面的情况下改变了当前URL地址,往历史记录添加一条条目,除非刷新页面等操作

  • 状态对象

    state是一个JavaScript对象,popstate事件的state属性包含该历史记录条目状态对象的副本。

    状态对象可以是能被序列化的任何东西。原因在于Firefox将状态对象保存在用户的磁盘上,以便在用户重启浏览器时使用,我们规定了状态对象在序列化表示后有640k的大小限制。如果你给 pushState() 方法传了一个序列化后大于640k的状态对象,该方法会抛出异常。如果你需要更大的空间,建议使用 sessionStorage 以及 localStorage.

  • 标题

    Firefox 目前忽略这个参数,但未来可能会用到。在此处传一个空字符串应该可以安全的防范未来这个方法的更改。或者,你可以为跳转的state传递一个短标题。

  • URL

    新的历史URL记录。新URL不必须为绝对路径。如果新URL是相对路径,那么它将被作为相对于当前URL处理。新URL必须与当前URL同源,否则 pushState() 会抛出一个异常。该参数是可选的,缺省为当前URL。

注意: pushState() 绝对不会触发 hashchange 事件,即使新的URL与旧的URL仅哈希不同也是如此。

更改历史记录中的当前条目

不会立即加载页面的情况下改变了当前URL地址,并改变历史记录的当前条目,除非刷新页面等操作

popstate 事件

每当活动的历史记录项发生变化时, popstate 事件都会被传递给window对象。如果当前活动的历史记录项是被 pushState 创建的,或者是由 replaceState 改变的,那么 popstate 事件的状态属性 state 会包含一个当前历史记录状态对象的拷贝。

获取当前状态

页面加载时,或许会有个非null的状态对象。这是有可能发生的,举个例子,假如页面(通过pushState() 或 replaceState() 方法)设置了状态对象而后用户重启了浏览器。那么当页面重新加载时,页面会接收一个onload事件,但没有 popstate 事件。然而,假如你读取了history.state属性,你将会得到如同popstate 被触发时能得到的状态对象。

你可以读取当前历史记录项的状态对象state,而不必等待popstate 事件

思路

监听点击事件禁止默认跳转操作,手动利用history实现一套跳转逻辑,根据location.pathname渲染界面.

具体代码可以查看html5_demo.html
注意,该方法不支持本地运行,只能线上运作或者启动服务器查看效果

html5_demo.html:26 Uncaught DOMException: Failed to execute 'pushState' on 'History': A history state object with URL 'file:///C:/b' cannot be created in a document with origin 'null' and URL 'file:///C:/work/project/router_demo/src/html5_demo.html'.
at HTMLAnchorElement.<anonymous> (file:///C:/work/project/router_demo/src/html5_demo.html:26:15)
(anonymous) @ html5_demo.html:26

简单封装路由库

API

基本的路由方法:

  • router.push(url, onComplete)
  • router.replace(url, onComplete)
  • router.go(n)
  • router.back()
  • router.stop()

初始化

router类

Hash Class

HTML5 Class

完整代码可以拷贝router_demo

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复