一、路由历史
传统的服务端路由,是根据客户端请求的不同地址,返回不同的网页内容。SPA之后,在url地址改变的过程中,通过js来实现不同UI之间的切换,也就是用js对DOM的操作。其中,根据url地址栏的变化二展示不同的UI,就属于前端路由。
二、前端路由
1. 基于hash
在HTML5的history API出现之前,前端路由主要是通过hash来实现的,hash能兼容低版本的浏览器。
location.hash是url中#之后的内容,与hash密切相关的是hashChange事件,在hash变化的时候会触发。hash要满足以下条件:
(1)url中hash值的变化不会重新加载页面,hash是用来指导浏览器行为的,对服务端是无用的,所以不会包括在http请求中;
(2)hash值的变化,都会在浏览器的访问历史中增加一个记录,也就是能通过浏览器的回退、前进按钮控制hash的切换;
(3)可以用欧hashchange事件,监听到hash值的变化,从而响应不同路径的逻辑处理。
window.addEventListener('hashchange', fuction, false);
我们可以在hashchange事件里,根据hash值来更新对应的视图,但不会去重新请求页面,同事在history中增加一条访问记录,用户仍然可以通过前进后退键实现UI的切换。
改变hash有两种方式:
(1)通过a标签,设置href属性;
(2)js赋值location.hash;
route与router的区别:route是一条路由,是将一个URL路径和一个处理函数相关联,的映射规则;router像是一个容器,它管理了一组route。当接收到一个URL的时候,去路由映射表中查找响应的函数,这个过程是有router来处理的。
2. 基于History API
HTML5 History API包括两个方法,history.pushState()和history.replaceState(),一个事件,window.onpopState。pushState与replaceState方法都包括三个参数:
window.history.pushState(state object, title, url);
- 状态对象(state object):一个JS对象,与用pushState方法创建的新历史记录条目关联,无论何时用户导航到新创建的状态,会触发popstate事件,并能在事件中使用该对象。
- 标题(title):传入一个短标题给当前state,现在大多数浏览器不支持或者会忽略此参数,最好传入null;
- 地址(url):新的历史记录条目的地址。新的url不一定是绝对路径,如果是相对路径,它将以当前url为基准。传入的url与当前url应该是同源的,否则,pushState会抛出异常。
pushState与replaceState的相同之处是都会操作浏览器的历史记录,而不会引起页面的刷新。不同之处在于pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录。
onpopstate事件会在调用浏览器的前进、后退以及执行history.forward、history.back、history.go时触发,这些操作有一个共性,即修改了历史堆栈的当前指针
三、history对象的坑
- 坑1
h5设定中,history.length属性无论如何,都是当前webview历史栈的总长度。不管某个网页什么时候打开的,history.length都是相同的值。无论如何都不能直接拿到该网页在webview历史栈中的位置,所以无法随心所欲使用history.go方法。 - webview history方法
- history.back 如果存在历史的话,只能回到前一个页面,如果要移动的位置超出范围,则不会移动;
- history.go(-n) 如果存在历史的话,可以回到前n个页面,如果要移动的位置超出范围,则不会移动。
- 坑2
location.href会改变当前页面之后压入历史栈的页面,改变history.length。pushState与location.href类似,也会清除旧的条目。
- 坑3
浏览器对历史记录栈的存储总数有限制,chrome和firefox都是50。当历史记录栈超过限制后,历史记录的存储就会采用滚动的方式存储,也就是最底部的记录会从栈底移出。