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 相关文章推荐
拖动布局之保存布局页面cookies篇
Oct 29 Javascript
纯js简单日历实现代码
Oct 05 Javascript
ECMAScript6函数默认参数
Jun 12 Javascript
javascript匀速运动实现方法分析
Jan 08 Javascript
html+js实现简单的计算器代码(加减乘除)
Jul 12 Javascript
基于jquery实现的鼠标悬停提示案例
Dec 11 Javascript
JavaScript实现为事件句柄绑定监听函数的方法分析
Nov 14 Javascript
vue2.0学习之axios的封装与vuex介绍
May 28 Javascript
Vue中使用webpack别名的方法实例详解
Jun 19 Javascript
js计时事件实现圆形时钟
Mar 25 Javascript
node使用request请求的方法
Dec 20 Javascript
详解JavaScript中的执行上下文及调用堆栈
Apr 29 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
DOTA2 1月28日更新:监管系统降临刀塔世界
2021/01/28 DOTA
PHP数组操作汇总 php数组的使用技巧
2011/07/17 PHP
深入分析php中接口与抽象类的区别
2013/06/08 PHP
浅谈PHP调用Webservice思路及源码分享
2014/06/04 PHP
php两种无限分类方法实例
2015/04/21 PHP
Laravel框架集合用法实例浅析
2020/05/14 PHP
Ext面向对象开发实践(续)
2008/11/18 Javascript
javascript 日历提醒系统( 兼容所有浏览器 )
2009/04/07 Javascript
分析Node.js connect ECONNREFUSED错误
2013/04/09 Javascript
js中的数组Array定义与sort方法使用示例
2013/08/29 Javascript
制作jquery遮罩层效果导航菜单代码分享
2013/12/25 Javascript
jQuery中Ajax的get、post等方法详解
2015/01/20 Javascript
Node.js中child_process实现多进程
2015/02/03 Javascript
jQuery制作效果超棒的手风琴折叠菜单
2015/04/03 Javascript
一波JavaScript日期判断脚本分享
2016/03/06 Javascript
JS获取子窗口中返回的数据实现方法
2016/05/28 Javascript
Bootstrap3 内联单选和多选框
2016/12/29 Javascript
深入理解jquery的$.extend()、$.fn和$.fn.extend()
2017/07/08 jQuery
微信小程序转化为uni-app项目的方法示例
2020/05/22 Javascript
python自动化工具日志查询分析脚本代码实现
2013/11/26 Python
Python fileinput模块使用实例
2015/06/03 Python
Python numpy 提取矩阵的某一行或某一列的实例
2018/04/03 Python
Python多线程应用于自动化测试操作示例
2018/12/06 Python
在pycharm中使用git版本管理以及同步github的方法
2019/01/16 Python
基于Python函数和变量名解析
2019/07/19 Python
python BlockingScheduler定时任务及其他方式的实现
2019/09/19 Python
使用Python进行中文繁简转换的实现代码
2019/10/18 Python
HTML5页面音视频在微信和app下自动播放的实现方法
2016/10/20 HTML / CSS
台湾屈臣氏网路商店:Watsons台湾
2020/12/29 全球购物
介绍一下Linux文件的记录形式
2013/09/29 面试题
最新党员的自我评价分享
2013/11/04 职场文书
门卫岗位职责
2013/11/15 职场文书
《搭石》教学反思
2014/04/07 职场文书
综合实践活动总结
2014/05/05 职场文书
大学生求职自荐信范文
2015/03/04 职场文书
高考诚信考试承诺书
2015/04/29 职场文书