• js


    零、引言
      本篇是关于 window.location (history/hash) 的尝试,算是为了学习各种 router 的基础吧。

      参考资料:
        1. url 中的 hash;
     

    一、基础准备

      基础的 index.html 页面。
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>js - router</title>
    </head>
    <body>
      <ul>
        <!-- 定义路由 -->
        <li><a href="#/home">home</a></li>
        <li><a href="#/about">about</a></li>
    
        <!-- 渲染路由对应的 UI -->
        <div id="routeView"></div>
      </ul>
    
      <!-- 不同场景下引入对应文件 -->
      <!-- <script src="hash.js"></script> -->
      <!-- <script src="history.js"></script> -->
    </body>
    </html>
    

    二、hash(#)

      最开始是用在 a 标签的 href 中,用来跳转到页面的指定位置,当然,因为经常与 id 选择器一起使用,所以一开始经常认为单纯的是 id 选择器。在 H5 更新的标准中,它有了更多的意义。
    上面参考资料中提及的需要注意的地方是 4.5.7 三点,因此也有了我们接下来的实践:
    // 维护 UI 页面
    let routerView = null;
    
    // 路由变化时,根据路由渲染对应的 ui 页面
    function onHashChange() {
      switch (window.location.hash) {
        case '':
        case '#/home':
          routerView.innerHTML = 'Home';
          return ;
        case '#/about':
          routerView.innerHTML = 'About';
          break;
        default:
          break;
      }
    }
    
    // 页面加载完不会触发 hashchange,这里主动触发一次 hashchange 事件。
    window.addEventListener('DOMContentLoaded', () => {
      routerView = document.querySelector('#routeView');
      onHashChange();
    })
    
    // 监听路由变化。
    window.addEventListener('hashchange', onHashChange);
    

    三、history

      history 在 H5 标准中新增了 pushState/replaceState 两个 api,这两均能够修改浏览器的历史记录,同时也方便了在写代码的过程中对页面流向的控制,不过也存在些问题,下一个章节进行比较。
    先看实践:
    // 维护 UI 页面。
    let routerView = null;
    
    // 路由变化时,根据路由渲染对应 UI 页面。
    function onPopState() {
      switch (window.location.pathname) {
        case '/':
        case '/home':
          routerView.innerHTML = 'Home';
          return ;
        case '/about':
          routerView.innerHTML = 'About';
          break;
        default:
          break;
      }
    }
    
    // 页面加载完不会触发 onPopState, 这里主动触发一次 onPopState 事件。
    window.addEventListener('DOMContentLoaded', () => {
      routerView = document.querySelector('#routeView');
      // 刷新页面。
      onPopState();
    
      // 拦截 <a> 标签点击事件默认行为, 点击时使用 pushState 修改 URL并更新手动 UI,从而实现点击链接更新 URL 和 UI 的效果。
      let links = document.querySelectorAll('a[href]');
      links.forEach(el => {
        el.addEventListener('click', e => {
          e.preventDefault();
          // 手动拦截
          window.history.pushState(null, '', el.getAttribute('href'));
          onPopState();
        })
      })
    })
    
    // 监听路由变化。
    window.addEventListener('popstate', onPopState);
    
    和 hash 的处理思路相同,调用的 api 略有区别,增加了取消 DOM 元素的原生事件步骤。
     

    四、两者的特点

      1. hash -- 即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。比如这个 URL:http://www.abc.com/#/hello,hash 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
      2. history -- 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
     
      所以呢, 在 hash 模式下,无论怎么刷新网页,浏览器一直是请求的同一个 index.html 文件,所以服务器不需要做额外的处理,只是显示在 url 栏中不那么美观。但是在 history 模式下,前进/后退等操作也只是修改的本地浏览器的历史栈,不发请求,刷新就不同了,这个操作会实打实地去请求当前 url 对应的资源,这意味着服务器不做处理,分分钟是 404,因此 vue-router 文档中强调开启 history 需要服务器支持。
     
  • 相关阅读:
    uboot学习之三-----uboot启动第一阶段--start.S之一
    4.7 C语言的存储类,作用域,生命周期,链接属性
    uboot学习之二----主Makefile学习之一----版本号 u_boot_version(U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL).$(EXTRAVERSION)) (24-29行)
    uboot学习之二----主Makefile学习之二----环境变量之:主机的操作系统和主机架构(HOSTOS、HOSTARCH)(31-43行)
    uboot学习之二----主Makefile学习之三----静默编译
    uboot学习之二----主Makefile学习之四----两种编译方法:原地编译和单独输出文件夹编译
    Linux下安装交叉工具链&&安装vim
    善变的不只是女人,还有volatile ---偷来的标题名
    东芝半导体最新ARM开发板——TT_M3HQ开箱评测
    STM32F407外部晶体改为25M后检测不到芯片的解决办法
  • 原文地址:https://www.cnblogs.com/cc-freiheit/p/12966157.html
Copyright © 2020-2023  润新知