你晓得前端单页面路由是怎样完成的吗?

首先要进修一下history对象,history对象保存着用户的上网纪录,从阅读器窗口翻开的那一刻算起。出于平安的斟酌,开发人员没法得知用户阅读过的URL。不过,借由用户接见过的页面列表,一样能够在不知道现实URL的情况下完成退却与行进

一、history对象的要领

go(Stirng|number)

运用go要领能够在用户的汗青纪录中恣意跳转,能够向后也能够向前。这个要领接收一个参数,示意向后或向前跳转的页面数的一个整数值。负数示意向后跳转(相似阅读器的退却按钮),正数示意向前跳转(相似阅读器的行进按钮)。来看下例子

//退却一页
history.go(-1)

//行进一页
history.go(1)

//行进两页
history.go(2)

也能够给go()要领船体一个字符串参数,此时阅读器会跳转到汗青纪录中包括改字符串的第一个位置,能够退却也能够行进,详细要看哪个位置近来。假如汗青纪录中不包括该字符串,则什么都不做。比方:

//跳转到近来的wrox.com页面
history.go("wrox.com")

//跳转到近来的douban.cn页面
history.go("douban.cn")

back()forward

这两个要领能够来替代go(),模拟阅读器的退却和行进功用

back()相当于 go(-1) 退却一个页面

forward相当于go(1) 行进一个页面

注:接下来几个要领是html5新增的要领

二、html5中history新增的要领

pushState(state,title,url)

该要领的作用是 在汗青纪录中新增一条纪录,转变阅读器地址栏的url,然则,不革新页面

pushState对象接收三个参数,

  • state:一个与增加的纪录相关联的状况对象,重要用于popstate事宜。该事宜触发时,该对象会传入回调函数。也就是说,阅读器会将这个对象序列化今后保留在当地,从新载入这个页面的时刻,能够拿到这个对象。假如不须要这个对象,此处能够填null
  • title:新页面的题目。然则,如今一切阅读器都无视这个参数,所以这里能够填空字符串。
  • url:新的网址,必需与当前页面处在同一个域。阅读器的地址栏将显现这个网址。

举个例子,假定当前网址是hello.com/1.html,运用puchState()要领在阅读纪录中增加一个新纪录

var stateObj={foo:'bar'}
history.pushState(starteObj,'','2.html')

增加新纪录后,阅读器的地址栏马上显现`hello.com/2.html,但不会跳转到2.html,也不会搜检2.html是不是存在,它只是成为阅读汗青中的最新纪录。

总之,pushState()要领不会触发页面革新,只是致使history对象发作变化,地址栏会有回响反映,运用该要领后,就能够运用history.state属性读出状况对象

var stateObj={foo:'bar'}
history.pushState(starteObj,'','2.html')
history.state //=> {foo:"bar"}

注重:假如pushState的URL参数设置了一个新的hash值,并不会触发hashchange事宜。

replaceState(state,title,url)

replaceState要领的作用是替代当前的汗青纪录,其他的都与pushState()要领如出一辙。

假定当前网页是example.com/example.html

history.pushState({page: 1}, 'title 1', '?page=1')
// URL 显现为 http://example.com/example.html?page=1

history.pushState({page: 2}, 'title 2', '?page=2');
// URL 显现为 http://example.com/example.html?page=2

history.replaceState({page: 3}, 'title 3', '?page=3');
// URL 显现为 http://example.com/example.html?page=3

history.back()
// URL 显现为 http://example.com/example.html?page=1

history.back()
// URL 显现为 http://example.com/example.html

history.go(2)
// URL 显现为 http://example.com/example.html?page=3

三、popstate事宜

popstate事宜是
window对象上的事宜,合营pushState()和replaceState()要领运用。当
同一个文档(能够理解为同一个网页,不能跳转,跳转了就不是同一个网页了)的阅读汗青涌现变化时,就会触发popstate事宜。

上面我们说过,挪用pushState()或许replaceState()要领都邑转变当前的汗青纪录,仅仅挪用pushState()要领或replaceState()要领 ,并不会触发该事宜,别的一个前提是用户必需点击阅读器的倒退按钮或许行进按钮,或许运用js挪用history.back()或许history.forward()等要领。

所以,记着popstate事宜触发的前提

1. 处在同一个文档(同一个html页面)
2. 文档的阅读汗青(即history对象)发作转变

只需相符这两个前提,popstate事宜就会触发

详细例子

//index.html
<head>
    <script>
        window.onpopstate=function(){
            alert('location '+document.location+',state '+JSON.stringify(event.state))
        }
    </script>
</head>
<body>
    <!--第二步 -->
    <button onclick="window.history.back()">退却</button>
    <button onclick="window.history.forward()">行进</button>
    <!--第一步 -->
    <button onclick="window.history.pushState(null,'','1.html')">pushState</button>    
</body>

先点击pushState按钮,在点击退却按钮,就会触发popstate事宜

再来一个例子

//index.html
<head>
    <script>
        window.onpopstate=function(){
            alert('location '+document.location+',state '+JSON.stringify(event.state))
        }
    </script>
</head>
<body>
    <a href="#one">#one</a>   
</body>

直接点击a标签,也能够触发popstate事宜

四、阅读器兼容性

图片来自mdn传送门

《你晓得前端单页面路由是怎样完成的吗?》

五、单页面路由道理

前端路由的实质是监听 URL 的变化,然后婚配路由划定规矩,显现响应的页面,而且不必革新。

现在单页面运用的路由就只有两种完成体式格局

  • hash形式
  • history形式

hash形式

www.test.com/##/就是Hash URL,当##背面的哈希值发作变化时,不会向服务器要求数据,能够经由过程hashchange事宜来监听到URL的变化,从而举行跳转页面

网上偷来的一张图:

《你晓得前端单页面路由是怎样完成的吗?》

history形式

history形式比拟hash形式更雅观,须要用到Html5新增的几个api完成,道理以下:

继承偷图:

《你晓得前端单页面路由是怎样完成的吗?》

五、实例,运用history api完成简朴的单页面路由

在引见实例前先引见下location对象,location对象供应了与当前窗口中加载的文档有关的信息。它包括以下属性:

属性名例子申明
hostwww.hello.com:8080返回服务器称号和端口号(假如有的话)
hostnamewww.hello.com返回服务器称号,不带端口号
hrefhttp://www.hello.com返回当前加载页面的完全url
pathname/user/ming返回url中的目次
hash#content返回url中的hash,假如没有返回空字符串
search?q=javascript返回Url的查询字符串,这个字符串以问号开首

我们在下方的示例中须要用到pathname属性拿到接见的途径

一个简朴的history形式单页面路由完成以下:

//1. 路由划定规矩
const routes={
    '/user':user, //user是引入的视图   import user from './view/user' 
    '/about':about
}
//2. 路由掌握类
class Router {
  start() {
    // 点击阅读器退却/行进按钮时会触发window.onpopstate事宜, 我们在这时候切换到响应页面
    // https://developer.mozilla.org/en-US/docs/Web/Events/popstate
    window.addEventListener('popstate', () => {
      this.load(location.pathname)
    })

    // 翻开页面时加载当前页面 在单页面进口文件中要挪用start要领
    this.load(location.pathname)
  }

  // 前去path, 变动地址栏URL, 并加载响应页面
  go(path) {
    // 变动地址栏URL
    history.pushState({}, '', path)
    // 加载页面
    this.load(path)
  }

  // 加载path途径的页面
  load(path) {
    // 首页
    if (path === '/') path = '/foo'
    // 建立页面实例
    const view = new routes[path]()
    // 挪用页面要领, 把页面加载到document.body中
    view.mount(document.body)
  }
}

Router类的作用是掌握页面依据当前Url切换

  • start()

    • 作用1: 监听onpopstate事宜,在阅读器行进或退却时加载响应的页面
    • 作用2: 翻开页面时加载当前页面,须要在单页面的进口文件引入,并实行
  • go(path)

    • 跳转到path对应的页面
  • load(path)

    • 加载path途径的页面

参考链接

    原文作者:hyangteng
    原文地址: https://segmentfault.com/a/1190000018219705
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞