js单页hash路由原理与应用实战详解


Posted in Javascript onAugust 14, 2017

本文主要介绍了js单页hash路由原理与应用实战详解,分享给大家,具体如下:

什么是路由?

通俗点说,就是不同的URL显示不同的内容

什么是单页应用?

单页,英文缩写为SPA( Single Page Application),就是把各种功能做在一个页面内. 那所谓的单页路由应用就是:在一个页面内,通过切换地址栏的URL来实现切换内容的变化.

如何知道URL切换了呢?

当url后面的锚文本发生变化时, 会触发onhashchange事件。通过这个事件,我们就可以对不同的URL 做出不同的处理。锚文本就是 URL中 #后面的内容,比如:

#/html

#/css

#/javascript

<a href="#/html" rel="external nofollow" rel="external nofollow" >html课程</a> 
<a href="#/css" rel="external nofollow" rel="external nofollow" >css课程</a>
window.onload = function(){
      //当hash发生变化的时候, 会产生一个事件 onhashchange
      window.onhashchange = function(){
        console.log( '你的hash改变了' );
        //location对象是 javascript内置的(自带的)
        console.log( location );
      }
    }

上例,我们已经通过hash( 就是锚文本 ) 变化, 触发了onhashchange事件, 就可以把hash变化 与 内容 切换对应起来,就实现了单页路由的应用!

接下来,我们通过一个小的彩票程序,来体验下单页路由:

<input type="button" value="33选5">
 <div></div>
window.onload = function(){
      var oBtn = document.querySelector("input");
      var oDiv = document.querySelector("div");
      //33->max 5->num
      function buildNum( max, num ){
        var arr = [];
        for( var i = 0; i < max; i++ ){
          arr.push( i + 1 );
        }
        var target = []; //从1-33这33个数字中 随机选出5个数
        for( var i = 0; i < num; i++ ){
          target.push( arr.splice( Math.floor( Math.random() * arr.length ), 1 ) );
        }
        return target;
      }
      oBtn.onclick = function(){
        var num = buildNum( 33, 5 );
        oDiv.innerHTML = num;
        location.hash = num;
      }
      window.onhashchange = function(){
        oDiv.innerHTML = location.hash.substring(1);
      }
    }

上例,我们通过1-33个数字,生成5个随机数,放入Div中,  每次生成一组随机数就更新div的内容,  最后通过浏览器的前进,后退按钮,就可以感觉,所有的随机切换内容像是在切换不同的URL页面, 实际的效果是没有切换任何页面,完全是在一个页面中通过hash变化实现内容切换.

最后,我们结合html5简单的排版,利用hash来做一个选项卡切换的功能:

header,
    footer {
      height: 100px;
      background: #ccc;
    }

    section {
      width: 60%;
      height: 400px;
      background: #eee;
      float: left;
    }

    sidebar {
      width: 40%;
      height: 400px;
      background: #999;
      float: left;
    }

    .clear {
      clear: both;
    }
<header>
    头部
  </header>
  <section>
    <ul>
      <li><a href="#/" rel="external nofollow" >全部</a></li>
      <li><a href="#/html" rel="external nofollow" rel="external nofollow" >html课程</a></li>
      <li><a href="#/css" rel="external nofollow" rel="external nofollow" >css课程</a></li>
      <li><a href="#/javascript" rel="external nofollow" >javascript课程</a></li>
    </ul>
  </section>
  <sidebar>
    右边
  </sidebar>
  <div class="clear"></div>
  <footer>
    底部
  </footer>
(function(){
      var Router = function(){
        /*
          this.routes['/'] = function(){}  
          this.routes['/html'] = function(){}
        */ 
        this.routes = {};//用来保存路由
        this.curUrl = ''; //获取当前的hash
      }
      Router.prototype.init = function(){ //监听路由变化
        //call,apply
        window.addEventListener( 'hashchange', this.reloadPage.bind(this) );
      }
      Router.prototype.reloadPage = function(){
        this.curUrl = location.hash.substring(1) || '/';
        this.routes[this.curUrl]();    
      }
      Router.prototype.map = function( key, callback ){ //保存路由对应的函数
        this.routes[key] = callback;
        // console.log( this.routes );
      } 
      window.Router = Router;
    })();

    var oRouter = new Router();
    oRouter.init();
    oRouter.map( '/', function(){
      var oSidebar = document.querySelector("sidebar");
      oSidebar.innerHTML = 'ghostwu提供html,css,javascript从0基础到精通系列课程,只要会开关机,就能学会';
    });
    oRouter.map('/html', function(){
      var oSidebar = document.querySelector("sidebar");
      oSidebar.innerHTML = 'ghostwu提供html5从入门到精通的课程';
    });
    oRouter.map('/css', function(){
      var oSidebar = document.querySelector("sidebar");
      oSidebar.innerHTML = 'ghostwu提供从入门到玩转css3课程';
    });
    oRouter.map('/javascript', function(){
      var oSidebar = document.querySelector("sidebar");
      oSidebar.innerHTML = "ghostwu提供从0基础到精通javascript系列课程";
    });

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 选择文件夹对话框(web)
Jul 07 Javascript
JS 获取浏览器和屏幕宽高等信息的实现思路及代码
Jul 31 Javascript
JS获取屏幕,浏览器窗口大小,网页高度宽度(实现代码)
Dec 17 Javascript
javascript实现验证IP地址等相关信息代码
May 10 Javascript
基于PHP和Mysql相结合使用jqGrid读取数据并显示
Dec 02 Javascript
jQuery抛物线运动实现方法(附完整demo源码下载)
Jan 08 Javascript
JavaScript检查子字符串是否在字符串中的方法
Feb 03 Javascript
jquery-mobile表单的创建方法详解
Nov 23 Javascript
Restify中接入Socket.io报Error:Can’t set headers的错误解决
Mar 28 Javascript
详解react-router如何实现按需加载
Jun 15 Javascript
Vue 兄弟组件通信的方法(不使用Vuex)
Oct 26 Javascript
vue 自定义提示框(Toast)组件的实现代码
Aug 17 Javascript
jQuery选择器特殊字符与属性空格问题
Aug 14 #jQuery
详解升级react-router 4 踩坑指南
Aug 14 #Javascript
javaScript封装的各种写法
Aug 14 #Javascript
vue教程之toast弹框全局调用示例详解
Aug 24 #Javascript
vue2.0项目中使用Ueditor富文本编辑器示例代码
Aug 14 #Javascript
jQuery实现手势解锁密码特效
Aug 14 #jQuery
Vue+Element使用富文本编辑器的示例代码
Aug 14 #Javascript
You might like
基于wordpress主题制作的具体实现步骤
2013/05/10 PHP
使用PHP和HTML5 FormData实现无刷新文件上传教程
2014/09/06 PHP
php实现Mongodb自定义方式生成自增ID的方法
2015/03/23 PHP
yii2中添加验证码的实现方法
2016/01/09 PHP
Laravel使用消息队列需要注意的一些问题
2017/12/13 PHP
PHP实现通过strace定位故障原因的方法
2018/04/29 PHP
IE6下JS动态设置图片src地址问题
2010/01/08 Javascript
jquery获取特定name所有选中的checkbox,支持IE9标准模式
2013/03/18 Javascript
jquery ajax 局部无刷新更新数据的实现案例
2014/02/08 Javascript
javascript匿名函数应用示例介绍
2014/03/07 Javascript
js取得html iframe中的元素和变量值
2014/06/30 Javascript
给js文件传参数(详解)
2014/07/13 Javascript
js使用正则实现ReplaceAll全部替换的方法
2014/07/18 Javascript
基于jQuery实现网页进度显示插件
2015/03/04 Javascript
javascript 闭包详解
2015/07/02 Javascript
浅谈angularJS 作用域
2015/07/05 Javascript
JS实现自动定时切换的简洁网页选项卡效果
2015/10/13 Javascript
javascript cookie的简单应用
2016/02/24 Javascript
深入理解Angular2 模板语法
2016/08/07 Javascript
深入理解Angular4中的依赖注入
2017/06/07 Javascript
基于JavaScript实现无限加载瀑布流
2017/07/21 Javascript
vue实现简单瀑布流布局
2020/05/28 Javascript
[06:25]DOTA2英雄梦之声_第17期_大地之灵
2014/06/20 DOTA
TensorFlow模型保存和提取的方法
2018/03/08 Python
Python生成器定义与简单用法实例分析
2018/04/30 Python
django表单实现下拉框的示例讲解
2018/05/29 Python
使用Windows批处理和WMI设置Python的环境变量方法
2019/08/14 Python
python数值基础知识浅析
2019/11/19 Python
python使用python-pptx删除ppt某页实例
2020/02/14 Python
python 在threading中如何处理主进程和子线程的关系
2020/04/25 Python
用python 绘制茎叶图和复合饼图
2021/02/26 Python
英国首屈一指的票务公司:See Tickets
2019/05/11 全球购物
小学教师的个人自我鉴定
2013/10/26 职场文书
业务内勤岗位职责
2015/04/13 职场文书
Django如何与Ajax交互
2021/04/29 Python
深入理解pytorch库的dockerfile
2022/06/10 Python