详解单页面路由的几种实现原理(附demo)
前言
路由是每个单页面网站必须要有的,所以,理解一下原理,我觉得还是比较重要的。
本篇,基本不会贴代码,只讲原理,代码在页底会有githup地址,主意,一定要放在服务本地服务器里跑(因为有ajax),
希望能帮到你。
众所周知单页面网站的路径跳转全是通过js来控制的,下面咱们来讲讲
第一种:url完全不动型
这一种的情况是url完全不动,即你的页面怎么改变,怎么跳转url都不会改变
这种情况的原理 就是纯ajax拿到页面后替换原页面中的元素,
这种情况没什么好讲的,好的一言不和上代码 demo(地址在页底) 这里有全部的代码
第二种:带hash(#)型
这种类型的优点就是刷新页面,页面也不会丢。
实现原理:
小明说:如果window有一个事件能让我监听url的变化,那我就能实先路由,
那样我就可以根据url的变化,来通过ajax请求参数来渲染页面,
一个url对应一个页面,也不会重复,多好了。
我:还真有,但是只能监听 #后面参数的变化。
小明说:唉,那就凑合一下把。
通过监听 hash(#)的变化来执行js代码 从而实现 页面的改变
核心代码:
window.addEventListener(‘hashchange‘,function(){
self.urlChange()
})
就是通过这个原理 只要#改变了 就能触发这个事件,这也是很多单页面网站的url中都也 (#)的原因
demo在下面
第三种:无hash(#)型
这种类型是通过html5的最新history api来实现的 能正常的回退前进 很好
url是这样的 www.ff.ff/jjkj/fdfd/fdf/fd 和普通的url一样,但是也有缺点 ,就是一刷新页面 页面就会丢,
因为 只要刷新 这个url(www.ff.ff/jjkj/fdfd/fdf/fd)就会请求服务器,然而服务器上根本没有这个资源,所以就会报404,解决方案就 配置一下服务器端(可以百度一下)
实现原理:
用了 这几个 api
history.pushState
history.replaceState
history.state
window.onpopstate事件
第一步:history.pushState(null,null,"/abc"); 改变url
第二部:执行一个函数(这个函数里有改变页面的代码)
就这末简单。
下面讲一下这几个api怎么用
pushState是将指定的URL添加到浏览器历史里,存储当前历史记录点API:history.pushState(state, title, url)
// @state状态对象:记录历史记录点的额外对象,可以为空
// @title页面标题:目前所有浏览器都不支持
// @url可选的url:浏览器不会检查url是否存在,只改变url,url必须同域,不能跨域
history.pushState的目的
SEO优化
更少的数据请求
更好的用户体验
history.replaceState
replaceState是将指定的URL替换当前的URL,替换当前历史记录点
replaceState的api和pushState类似,不同之处在于replaceState不会在window.history里新增历史记录点,而pushState会在历史记录点里新增一个记录点的
history.state
当前URL下对应的状态信息。如果当前URL不是通过pushState或者replaceState产生的,那么history.state是null。
state对象虽然可以存储很多自定义的属性,但对于不可序列化的对象则不能存储
window.onpopstate事件
window.onpopstate事件主要是监听历史记录点,也就是说监听URL的变化,但会忽略URL的hash部分。
history.go和history.back(包括用户按浏览器历史前进后退按钮)触发,并且页面无刷的时候(由于使用pushState修改了history)会触发popstate事件,事件发生时浏览器会从history中取出URL和对应的state对象替换当前的URL和history.state。通过event.state也可以获取history.state。
注意点:
javascript脚本执行window.history.pushState和window.history.replaceState不会触发onpopstate事件。
谷歌浏览器和火狐浏览器在页面第一次打开的反应是不同的,谷歌浏览器奇怪的是回触发onpopstate事件,而火狐浏览器则不会。
最后:
这3个demo 实现的还算可以,代码结构也还好把,最长的120多行,相信你可以看的懂,如果真的项目中需要用的话,,那那代码结构还需要优化一下,
本来我还想着把这3个deom给整合一下呢,变成一个功能完备的路由,唉,最近活多啊,下次吧!!!!
好了 是给 完整例子的时候了 demo
原文地址:http://www.cnblogs.com/xiaobie123/p/6357724.html