zoukankan      html  css  js  c++  java
  • 前端路由的实现(三) —— History的pushState和replaceState用法

    HTML5中history提供的pushStatereplaceState这两个API。它们提供了操作浏览器历史栈的方法。

    pushState能够在不加载页面的情况下改变浏览器的URL。这个方法接受三个参数:

    状态对象新状态的标题可选的相对URL。

     history.pushState(data, null, '#/page=1');
        pushState接收3个参数,第一个参数为一个obj,表示浏览器的state属性;
        第二个参数是document.title的值,一般设定为`null`;
        第三个参数string,用以改变当前url

    pushState方法在改变url的同时向浏览器历史栈中压入新的历史记录

    接收url的参数为string类型,用以改变当前地址栏的url.需要注意的一点就是这个参数不能和跨域,即协议,域名,端口必须都是相同的,如果出现跨域的情况,即会提示:

    Example:

    其中 replaceState:

      replaceState接收的参数pushState相同,但是最终的效果是:地址栏url会根据接收的参数而变化,但是浏览器并未在当浏览历史栈中增加浏览器的历史记录,而是替换当前的浏览器历史记录。

    通过pushStatereplaceState虽然能改变URL,但是不会主动触发浏览器reload

    window对象还提供 popstate方法

    这个方法用以监听浏览器在不同历史记录中进行切换,而触发相应的事件

    在浏览器提供的history对象上还有goback方法,用以模拟用户点击浏览器的前进后退按钮。在某个web应用当中,比如点击了<a>标签,发生了页面的跳转。这时调用history.back()方法后页面回退,同时页面发生刷新,这时window.onpopstate无法监听这个事件。但是如果是通过pushState或者replaceState改变URL不发生浏览器刷新的话,再使用history.back()history.go(),这样popstate事件会被触发

    输出如下:

    注意:  通过pushState在url上添加?page=1可以通过location.search去获取search的内容。不过如果通过location.search去改变url的话是会主动触发浏览器reload的。

    API大致了解了,那么这些方法可以运用到哪些地方呢?一个比较常用的场景是就在单页应用中,通过这些API完成前端的路由设计,利用pushStatereplaceState可以改变url同时浏览器不刷新,并且通过 popstate 监听浏览器历史记录的方式,完成一系列的异步动作。

    简单的路由如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Document</title>
      <style>
        a {color: red;text-decoration: underline;}
      </style>
    </head>
    <body>
      <a data-href="/post">post</a>
      <a data-href="/login">login</a>
      <script>
           const Router = [];
           const addRoute = (path ='', handle=() =>{}) => {
            let obj = {
              path,
              handle
            };
            Router.push(obj);
           }
           // 添加路由定义
           addRoute('/post', function(){
            // todo...
              alert('/post');
           })
           addRoute('/login', function(){
            // todo...
             alert('login');
           })
           // 路由处理
           const routeHandle = (path) => {
            for(var item of Router){
              if (item.path === path) {
                item.handle.apply(null, [path]);
                return true;
              }
            }
           }
           document.addEventListener('click', function(e) {
            let dataset = e.target.dataset;
            if(dataset) {
                if(routeHandle(dataset.href)) {
                    var url = window.location.href;
                    history.pushState({route: dataset.href}, null, oriUrl + dataset.href);
                    //阻止默认行为
                    return false;
                    // e.preventDefault();
                }
            }
        })
      </script>
    </body>
    </html>

    大致的实现思路就是,通过<a>添加路由信息,然后拦截<a>标签的默认行为,并与注册的路由信息进行匹配。若匹配成功调用对应的handle方法

  • 相关阅读:
    数据库迁移到Amazon RDS 的问题
    排序算法之希尔排序
    第一个 Shell脚本
    排序算法之直接插入排序
    当前工作参考
    cerr
    阿里云典型应用案例
    云服务引擎ACE
    阿里云SLB
    指针使用注意事项
  • 原文地址:https://www.cnblogs.com/xuzhudong/p/8886752.html
Copyright © 2011-2022 走看看