彻底搞懂路由跳转:location 和 history 接口

在单页应用中,通常由前端来配置路由,根据不同的 url 显示不同的内容。想要知道这是如何做到的,首先得了解浏览器提供的两大 API:

  1. window.location

    • location.href
    • location.hash
    • location.search
    • location.pathname
  2. window.history

    • history.pushState()
    • history.replaceState()
    • history.go()
    • history.back()
    • history.forward()

window.location

我们先了解 location 对象,location 有很多的属性。我们可以通过改变其属性值修改页面的 url。我们在单页应用中需要做到的是改变 url 不刷新页面,location 接口提供以下两种方式可以做到:

  1. location.href 赋值时只改变 url 的 hash
    图片描述
  2. 直接赋值 location.hash
    图片描述

而上面的列出其余两个属性 location.search 会直接刷新页面,这个就不解释了。但 location.pathname 照道理来说只改变 hash 应该是可以的,但实际上浏览器会编码这个属性值,所以无法直接赋带 # 号的值。

window.history

history 接口是 HTML5 新增的,它有五个方法可以改变 url 而不刷新页面。

  1. history.pushState()
    图片描述
  2. history.replaceState()
    图片描述
  3. history.go()
    图片描述

上面只演示了三个方法,因为 history.back() 等价于 history.go(-1)history.forward() 则等价于 history.go(1),这三个接口等同于浏览器界面的前进后退。

如何监听 url 的变化

现在我们已经知道如何不刷新页面改变页面的 url。虽然页面没刷新,但我们要改变页面显示的内容。这就需要 js 监听 url 的变化从而达到我们的目的。

我们有两个事件可以监听 url 的改变:

hashchange

hashchange 事件能监听 url hash 的改变。

先要加上事件监听的代码:

window.addEventListener('hashchange', function(e) {
  console.log(e)
})

然后就可以在页面的 console 里愉快的实验了:

图片描述

从上图中我们可以知道不管是通过 location 接口直接改变 hash,还是通过 history 接口前进后退(只是 hash 改变的情况下),我们都可以监听到 url hash 的改变。但这个事件也只能监听 url hash 的变化。所以我们需要一个更强大的事件:popstate

popstate

popstate 事件能监听除 history.pushState() 和 history.replaceState() 外 url 的变化。

先加上事件监听的代码:

window.addEventListener('popstate', function(e) {
  console.log(e)
})

然后又可以在页面的 console 里愉快的实验了:

图片描述

其实不止 history.pushState() 和 history.replaceState() 对 url 的改变不会触发 popstate 事件,当这两个方法只改变 url hash 时也不会触发 hashchange 事件。

hash 模式和 history 模式

我们都知道单页应用的路由有两种模式:hash 和 history。如果我们在 hash 模式时不使用 history.pushState() 和 history.replaceState() 方法,我们就只需要在 hashchange 事件回调里编写 url 改变时的逻辑就行了。而 history 模式下,我们不仅要在 popstate 事件回调里处理 url 的变化,还需要分别在 history.pushState() 和 history.replaceState() 方法里处理 url 的变化。而且 history 模式还需要后端的配合,不然用户刷新页面就只有 404 可以看了?

所以 hash 模式下我们的工作其实是更简单的,但为什么现在都推荐用 history 模式呢?总不是 hash 模式下的 url 太丑了,毕竟这是个看脸的世界?

不过 vue-router 在浏览器支持 pushState() 时就算是 hash 模式下也是用 history.pushState() 来改变 url,不知道有没什么深意?还有待研究...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值