详解单页面路由的几种实现原理(附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        

 

posted on 2017-01-29 22:56  我是路飞同志们  阅读(4483)  评论(1编辑  收藏  举报