【前端路由】实现一个 hash、history 路由,改善页面渲染体验

⭐️ 本文首发自 前端修罗场(点击即可加入),一个专注 Web 技术、答疑解惑、面试辅导、职业发展的社区。现在加入,即可参与打卡挑战,挑战成功即可获取一次免费的模拟面试机会,进而评估知识点的掌握程度,获得更全面的学习指导意见!


路由的概念来源于服务端,在服务端中路由描述的是 URL 与处理函数之间的映射关系。

在 Web 前端单页应用 SPA(Single Page Application)中,路由描述的是 URL 与 UI 之间的映射关系,这种映射是单向的,即 URL 变化引起 UI 更新(无需刷新页面)。

实现前端路由

核心:

  • 不引起页面刷新
  • 检测URL变化

方法:

  • hash:URL中(#)及(#)后面的部分。通过hashchange事件监听URL变化,改变URL的方式:
    1. 通过浏览器前进后退改变URL
    2. 通过<a>标签改变URL
    3. 通过window.locatioin改变URL
  • history:提供pushStatereplaceState两个方法:
    1. 提供popstate事件,但popstate事件有些不同:
      • 通过浏览器前进后退改变URL时会触发popstate事件
      • 通过pushState/replaceState<a>标签改变URL时不会触发popstate事件
    2. 可以通过拦截pushState/replaceState的调用和<a>标签的点击事件来检测URL是否发生变化

实现方式(1):hash

<body>
  <!-- route -->
  <ul>
    <li>
      <a href="#/home">home</a>
    </li>
    <li>
      <a href="#/about">about</a>
    </li>
  </ul>
  <!-- view -->
  <div id="routerView"></div>
  <script>
    window.addEventListener('DOMContentLoaded',onLoad)
    //监听路由变化
    window.addEventListener('hashchange',onHashChange)
    let routerView = null;
    function onLoad() {
      routerView = document.querySelector('#routerView');
      onHashChange();
    }
    function onHashChange() {
      switch(location.hash) {
        case '#/home':
          routerView.innerHTML = 'HOME';
          return;
        case '#/about':
          routerView.innerHTML = 'About';
          return;
        default:
          routerView.innerHTML = '';
          return;
      }
    }
  </script>
</body>

实现方式2:history

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <ul>
    <li>
      <a href="/home">home</a>
    </li>
    <li>
      <a href="/about">about</a>
    </li>
    <div id="routeView"></div>
  </ul>
  <script>
    window.addEventListener('DOMContentLoaded',onLoad)
    //监听路由变化
    window.addEventListener('popstate',onPopState)

    //routeView
    let routeView = null;

    function onLoad () {
      routeView = document.querySelector('#routeView');
      onPopState()
      //拦截a标签点击事件,点击时使用pushState修改URL并手动更新routeView
      let linkList = document.querySelectorAll('a[href]')
      linkList.forEach(el => el.addEventListener('click',function(e){
        e.preventDefault()
        history.pushState(null,'',el.getAttribute('href'))
          onPopState()
      }))
    }

    function onPopState() {
      switch (location.pathname) {
        case '/home':
          routeView.innerHTML = 'HOME'
          return
        case '/about':
          routeView.innerHTML = 'About'
          return
        default:
          routeView.innerHTML = ''
          return
      }
    }
  </script>
</body>
</html>

我们看到,使用history的方式,需要多判断a标签点击事件并拦截。

❤️ 现在关注【前端修罗场】,后台回复【666】,即可获取一份【免费的优质学习资料】,一起学习,一起进步~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程轨迹_

期望和你分享一杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值