使用hash实现页面切换

最近在看浏览器相关的内容,看到hash和history相关的内容了,自然而然想起来vue-router的两种模式,一直以来只知道这两种最模式最明显的区别反应在url上。

即:hash会在浏览器地址后面增加#号,hirtory可以自定义地址。
例如这个地址http://127.0.0.1:8848/es6/vue/hash.html#hello #hello这个内容就被称为hash也被成为散列值
在正式开始写一个例子之前,你需要先知道hash模式的这些特点

  • hash不会随请求发送到服务器端,因此改变hash不会重载页面
  • 通过window.onhashchange事件来监听hash值改变,以此来获取新的url地址和旧的url地址
  • location.hash值的变化会直接反应到浏览器的地址栏,因此可以在浏览器看到

下面我们来介绍一下怎么来模拟实现一个类似Vue-router的功能:
插一嘴,后面有时间看一下vue-router源码对比实现一个vue-router,完美!
大致思路:

  • 注册路由表
  • 当检测到路由发生改变的时候,更新页面内容
    最后实现效果就是点击按钮可以切换页面内容,通过地址栏修改hash值也可以进行页面切换。
    哈哈哈,没有看错就是这么简单。。

下面看代码:
点击切换就相当于是router跳转的逻辑,不多做过多的解释。

//声明路由表
let routes = ["hello", "world"];
      //保存当前hash
      let currentTab;
      //初始化展示hello页面
      createElement("hello");
      //点击切换页面
      function handleClick(name) {
        window.location.hash = name;
        currentTab = name;
      }

实现路由监听
Q:为什么不直接使用window.location.hash?
A:因为window.location中的内容是改变后的地址才能反应过来的,我们需要在地址栏改变之前就要只要需要渲染哪个页面,然后对其进行什么样的操作。

//监听hash改变事件-路由改变后页面变化
      window.addEventListener("hashchange", function (e) {
        let currentHash = e.newURL.split("#")[1];
        let widnowHash = getHash();
        //如果两个hash都不存在则return
        if (!widnowHash && widnowHash) return;
        //容错处理,优先取hashchange事件中的hash
        currentHash ? (currentTab = currentHash) : (currentTab = getHash());
        //检测路由改变后,更新页面
        createElement(currentTab);
      });

更新页面
Q:为什么要这么模拟?
A:我们在框架中一般是用webpack来帮我们实现这些内容的。webpack打包好的js运行出来就是一个个的页面,我们if里面判断的代码就相当于是做了这么一件事情。

//模拟单页应用替换整个#app内内容的操作
      function createElement(currentTab) {
        let container = document.getElementById("container");
        //每次先清空container中的内容
        container.innerHTML = "";
        //创建标签
        let ele = document.createElement("div");
        ele.setAttribute("id", currentTab);
        if (currentTab === "hello") {
          ele.innerText = "this is hello page!!!";
        } else if (currentTab === "world") {
          ele.innerText = "this is world page!!!";
        }
        //将标签插入到container中
        container.appendChild(ele);
      }

参考链接:https://blog.csdn.net/Charissa2017/article/details/104779412
完整代码:
https://github.com/Cloverao/Interview/blob/master/js/hash.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容