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 相关文章推荐
基于jquery的一个图片hover的插件
Apr 24 Javascript
判断ie的两种简单方法
Aug 12 Javascript
自己封装的javascript事件队列函数版
Jun 12 Javascript
jQuery实现分章节锚点“回到顶部”动画特效代码
Oct 23 Javascript
基于jQuery实现仿搜狐辩论投票动画代码(附源码下载)
Feb 18 Javascript
AngularJS中的DOM操作用法分析
Nov 04 Javascript
JavaScript如何实现图片懒加载(lazyload) 提高用户体验(增强版)
Nov 30 Javascript
基于vue打包后字体和图片资源失效问题的解决方法
Mar 06 Javascript
vue移动端项目缓存问题实践记录
Oct 29 Javascript
layui 根据后台数据动态创建下拉框并同时默认选中的实例
Sep 02 Javascript
Vue + Node.js + MongoDB图片上传组件实现图片预览和删除功能详解
Apr 29 Javascript
解决vue项目axios每次请求session不一致的问题
Oct 24 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
PHP session 会话处理函数
2016/06/06 PHP
PHP序列化操作方法分析
2016/09/28 PHP
浅谈使用 Yii2 AssetBundle 中 $publishOptions 的正确姿势
2017/11/08 PHP
用js脚本控制asp.net下treeview的NodeCheck的实现代码
2010/03/02 Javascript
AJAX异步从优酷专辑中采集所有视频及信息(JavaScript代码)
2010/11/20 Javascript
javascript解决innerText浏览器兼容问题思路代码
2013/05/17 Javascript
JavaScript中innerHTML,innerText,outerHTML的用法及区别
2015/09/01 Javascript
jqGrid中文文档之选项设置
2015/12/02 Javascript
jQuery Mobile弹出窗、弹出层知识汇总
2016/01/05 Javascript
gameboy网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点
2016/02/21 Javascript
模板视图和AngularJS之间冲突的解决方法
2016/11/22 Javascript
使用ionic在首页新闻中应用到的跑马灯效果的实现方法
2017/02/13 Javascript
nodejs集成sqlite使用示例
2017/06/05 NodeJs
微信小程序 按钮滑动的实现方法
2017/09/27 Javascript
关于laydate.js加载laydate.css路径错误问题解决
2017/12/27 Javascript
jQuery中的$是什么意思及 $. 和 $().的区别
2018/04/20 jQuery
vue 项目打包通过命令修改 vue-router 模式 修改 API 接口前缀
2018/06/13 Javascript
Vue路由钩子之afterEach beforeEach的区别详解
2018/07/15 Javascript
微信小程序自定义弹出层效果
2020/05/26 Javascript
[02:15]2015国际邀请赛选手档案IG.Ferrari 430
2015/07/30 DOTA
python使用datetime模块计算各种时间间隔的方法
2015/03/24 Python
Python实例一个类背后发生了什么
2016/02/09 Python
java中两个byte数组实现合并的示例
2018/05/09 Python
如何安装多版本python python2和python3共存以及pip共存
2018/09/18 Python
Python合并2个字典成1个新字典的方法(9种)
2019/12/19 Python
Python使用socketServer包搭建简易服务器过程详解
2020/06/12 Python
将tf.batch_matmul替换成tf.matmul的实现
2020/06/18 Python
Scrapy-Redis之RedisSpider与RedisCrawlSpider详解
2020/11/18 Python
美国椅子和沙发制造商:La-Z-Boy
2020/10/25 全球购物
如何选择使用结构还是类
2014/05/30 面试题
经理管理专业自荐信范文
2013/12/31 职场文书
经典公益广告词
2014/03/13 职场文书
工作证明书
2015/06/15 职场文书
解决mysql模糊查询索引失效问题的几种方法
2021/06/18 MySQL
Centos系统通过Docker安装并搭建MongoDB数据库
2022/04/12 MongoDB
华为HarmonyOS3.0强在哪? 看看鸿蒙3.0这7个小功能
2023/01/09 数码科技