返回

前端路由 hash、history 模式探究:突破局限,领略真谛

前端

朋友们,早安!我是你们的老朋友,今天,咱们来聊聊前端路由。这两天,我一直在研究前端路由的 hash 和 history 模式。研究一番后,我得出一个结论:实现这两种模式并不像看起来那么容易。

我们先来了解一下 hash 模式。它的原理很简单:当我们改变 HTML 文件的哈希值(也就是 URL 地址后面加上一个 #value)时,浏览器不会发送请求。即使发送了请求(比如刷新页面),也不会带上哈希值。利用这个特性,我们可以通过监听哈希值的变化,然后根据 # 后面的参数操作 DOM,完成相应的页面跳转。这种模式的兼容性比较好,即使在不支持 HTML5 history API 的浏览器中也可以使用。

而 history 模式则不同,它利用了 HTML5 history API 中的 pushState() 和 replaceState() 方法来操作浏览器历史记录。当使用这些方法时,浏览器不会向服务器发送请求,而是改变当前页面的 URL,并在历史记录中添加或替换一个新的记录。这种模式的优点是可以获得更友好的 URL,并且在页面跳转时不会出现页面闪烁的情况。但是,它的兼容性不如 hash 模式好,只支持支持 HTML5 history API 的浏览器。

说了这么多,我们该怎么选择呢?如果你的项目需要兼容更多的浏览器,那么 hash 模式是一个不错的选择。但是,如果你更看重用户体验和 URL 的友好性,那么 history 模式更适合你。

现在,我们来实际操作一下。首先,我们创建一个 HTML 文件,并在其中添加一个按钮。点击这个按钮时,我们会修改 URL 的哈希值,并根据不同的哈希值显示不同的内容。代码如下:

<!DOCTYPE html>
<html>
<head>
  
</head>
<body>
  <button id="btn">点击我</button>
  <div id="content"></div>

  <script>
    document.getElementById('btn').addEventListener('click', function() {
      window.location.hash = 'page1';
    });

    window.addEventListener('hashchange', function() {
      const hash = window.location.hash;
      if (hash === '#page1') {
        document.getElementById('content').innerHTML = '这是页面1';
      } else if (hash === '#page2') {
        document.getElementById('content').innerHTML = '这是页面2';
      }
    });
  </script>
</body>
</html>

然后,我们来实现 history 模式。代码如下:

<!DOCTYPE html>
<html>
<head>
  
</head>
<body>
  <button id="btn">点击我</button>
  <div id="content"></div>

  <script>
    document.getElementById('btn').addEventListener('click', function() {
      history.pushState({ page: 'page1' }, null, 'page1');
    });

    window.addEventListener('popstate', function() {
      const state = history.state;
      if (state && state.page) {
        document.getElementById('content').innerHTML = '这是页面' + state.page;
      }
    });
  </script>
</body>
</html>

怎么样,朋友们,是不是很简单?好了,今天就聊到这里了。如果大家还有什么问题,欢迎在评论区留言。我是你们的老朋友,咱们下期再见!