框架hash/history实现简单原理

1.hahs

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Hash模式</title>
  </head>
  <body>
    <a href="#/home">home</a>
    <a href="#/about">about</a>
    <div id="content">default</div>
    <script>
      window.addEventListener('hashchange', () => {
        const content = document.getElementById('content')
        // 路径匹配显示
        window.location.hash === '#/home'
          ? (content.innerHTML = 'home')
          : (content.innerHTML = 'about')
      })
    </script>
  </body>
</html>

2.history

<!--
 * @Description:  需要在在服务器访问(可以使用anywhere建立一个文件服务器,或者vscode插件Live Server),否则无效
-->

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>history</title>
  </head>
  <body>
    <a href="/home">home</a>
    <a href="/about">about</a>
    <button onclick="test()">test</button>
    <button onclick="back()">back</button>
    <div id="content">default</div>
    <script>
      function back() {
        history.back()
      }
      function test(e) {
        console.log(' ssss')
        window.history.pushState({}, 'title', '/test')
      }
      const content = document.getElementById('content')
      const aEls = document.getElementsByTagName('a')
      ;[...aEls].forEach(item => {
        item.addEventListener('click', e => {
          // 阻止默认跳转时间
          e.preventDefault()
          const href = item.getAttribute('href')
          // 修改url
          history.pushState({}, '', href)
          // 修改显示内容
          content.innerHTML = href
        })
      })
      window.onpopstate = () => {
        // 会导致循环 back => pop => back => pop
        // history.back()
        console.log('hist', history)
        content.innerHTML = 'back'
      }
      let oldPushState = window.history.pushState
      window.history.pushState = function (state, title, path) {
        oldPushState.call(history, state, title, path)
        window.onpushstate && window.onpushstate(state, title, path)
      }
      window.onpushstate = window.onpopstate = function (state, title, path) {
        // back 的时候依然需要根据路径进行对应的渲染处理
        content.innerHTML = location.pathname
      }
    </script>
  </body>
</html>
posted @ 2024-04-15 10:29  story.Write(z)  阅读(6)  评论(0编辑  收藏  举报