zoukankan      html  css  js  c++  java
  • 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 需要服务器支持。
     
  • 相关阅读:
    android之APN
    Simple XML
    Retrofit – Java(Android) 的REST 接口封装类库
    Android 删除短信
    解决android:background背景图片被拉伸问题
    人分三等,你是哪一等?
    将android中的sample例子到eclipse中
    linux内存管理
    Android 使用android-support-multidex解决Dex超出方法数的限制问题,让你的应用不再爆棚(转)
    使用maven创建web项目
  • 原文地址:https://www.cnblogs.com/cc-freiheit/p/12966157.html
Copyright © 2011-2022 走看看