在以前的web程序中,路由字眼只出现在后台中。但是随着SPA单页面程序的发展,便出现了前端路由一说。单页面顾名思义就是一个网站只有一个html页面,但是点击不同的导航显示不同的内容,对应的url也会发生变化,这就是前端路由做的事。也就是通过JS实时检测url的变化,从而改变显示的内容。

目前很多前端框架都有接口去实现路由,比如vuejs的vue-route等。我们可以利用原生的hashchange事件来模拟一个简单的路由。

路由:
根据不同的url 显示 不同的内容
方法:
hash(锚链接)实现路由
history对象

1.首先要了解什么是hash,在这里你可以认为hash就是网址后面加上的 #/xxx

如下当点击 

<a href="#/html">html</a>
<a href="#/css">css</a>  内容时

<html>
<head runat="server" >
<meta charset="utf-8"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

<script src="Scripts/jquery-3.3.1.min.js"></script>
<script>
window.onload = function () {

//当hash发生变化的时候, 会产生一个事件 onhashchange
window.onhashchange = function () {
alert("你的Hash改变了");
alert(location);
console.log( location );

}

}

</script>
<title>JS路由</title>
</head>
<body>
<a href="#/html">html</a>
<a href="#/css">css</a>
</body>
</html>

2.实现一个简单的路由

location对象是 javascript内置的(自带的)

location 对象包含有关当前 URL 的信息。(也就是网址)

实现的功能:点击时从1-33里随机出现五个数,并按照这五个随机数改变hash,在按钮下方显示五个随机数

<html>
<head runat="server" >
<meta charset="utf-8"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

<script src="Scripts/jquery-3.3.1.min.js"></script>
<script>
window.onload = function () {

var OBtn = document.querySelector("input"); //获取第一个按钮
var OBtndiv = document.querySelector("div");//获取第一个输出随机数div盒子

OBtn.onclick = function () {
alert("1");
var num = BuildNum(33, 5);

location.hash = num;//点击时吧网址的hash改变成数组

}
window.onhashchange = function () {

OBtndiv.innerHTML = location.hash.substring(1);
}

function BuildNum(max, num) {
var arr = [];
for (var n = 0; n < max; n++) {
arr.push(n+1); //增加元素
}
var target = [];
for (var n = 0; n < num; n++) {
target.push(arr.splice(Math.floor(Math.random() * arr.length), 1));
// splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
// floor 向下取整
}//从1-33这33个数字中 随机选出5个数放入target数组

return target;
}
}

</script>

<title>JS路由</title>
</head>
<body>
<input type="button" value="33选5"/>
<div></div>
</body>
</html>

3.简单路由的运用 (简单框架雏形的运用) (简单的html5标签的运用)

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta charset="utf-8"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>

<script src="Scripts/jquery-3.3.1.min.js"></script>

<style>
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;
}
</style>

</head>
<body>
<header>
头部
</header>
<section>
<ul>
<li><a href="#/">啥都没有</a></li>
<li><a href="#/html">html</a></li>
<li><a href="#/css">css</a></li>
<li><a href="#/javascript">javascript</a></li>
</ul>
</section>
<sidebar>
右边
</sidebar>
<div class="clear"></div>
<footer>
底部
</footer>
<script>
//框架雏形:1.用一个立即表达式把框架包起来,避免代码污染(定义的变量..等重复使用)
// 2.在立即表达式里定义一个构造函数(这里指var Router);
// 3.最后加上语句window.objec = functionName;把函数暴露出来,
// 附加到window对象上面这样(这里指window.oRou );
// 4.在构造函数的原型对象上添加函数(init,reloadPage...)
// 5.用第3步附在window的构造函数构建一个新对象,//var oRouter2 = new oRou();
// 这个对象(oRouter2)就可以使用刚刚第4步添加的函数了;

(function () { //立即表达式:(function(){代码内容})();
var Router = function () { //构造函数
/*
this.routes['/'] = function(){}
this.routes['/html'] = function(){}
*/
this.routes = {};//用来保存路由
this.curUrl = ''; //获取当前的hash
}

Router.prototype.init = function () { //监听路由变化 当hash变化时调用reloadPage函数
//call,apply
// alert("添加hashchange调用的对象");
window.addEventListener('hashchange', this.reloadPage1.bind(this));
//第一个this指向window,bind里面的this指向调用这个函数的对象(这里是oRouter2)
}
Router.prototype.reloadPage1 = function () {
alert(location.hash.substring(1));
alert(location.hash);
this.curUrl = location.hash.substring(1) || '/';//获取当前hash的值(去掉#)

this.routes[this.curUrl](); //运行当前hsah值对应的函数
}
Router.prototype.map = function (key, callback) { //保存路由对应的函数:
alert(key +":" +callback)
this.routes[key] = callback; //key表示hash的值(去掉#),callback表示当前hash对应的函数
// console.log( this.routes );
}
window.oRou = Router;
})();

var oRouter2 = new oRou();
oRouter2.init();
oRouter2.map('/', function () {
alert("Zero")
var oSidebar = document.querySelector("sidebar");
oSidebar.innerHTML = '你点,你再点,你点点点';
});
oRouter2.map('/html', function () {
var oSidebar = document.querySelector("sidebar");
oSidebar.innerHTML = '狂拽 酷炫 吊炸天 的html';
});
oRouter2.map('/css', function () {
var oSidebar = document.querySelector("sidebar");
oSidebar.innerHTML = '狂 拽 酷 炫 吊 炸 天 的css';
});
oRouter2.map('/javascript', function () {
var oSidebar = document.querySelector("sidebar");
oSidebar.innerHTML = '狂拽酷炫吊炸天的javascript';
});
</script>
</body>
</html>

执行的过程   1.首先 执行init     2.init  执行并且调用函数对象

学习记录----简单的原生js路由的更多相关文章

  1. 一个简单用原生js实现的小游戏----FlappyBird

    这是一个特别简单的用原生js实现的一个小鸟游戏,比较简单,适合新手练习 这是html结构 <!DOCTYPE html><html lang="en">&l ...

  2. 封装一个简单的原生js焦点轮播图插件

    轮播图实现的效果为,鼠标移入左右箭头会出现,可以点击切换图片,下面的小圆点会跟随,可以循环播放(为了方便理解,没有补2张图做无缝轮播).本篇文章的主要目的是分享封装插件的思路. 轮播图我一开始是写成非 ...

  3. Java设计模式学习记录-简单工厂模式、工厂方法模式

    前言 之前介绍了设计模式的原则和分类等概述.今天开启设计模式的学习,首先要介绍的就是工厂模式,在介绍工厂模式前会先介绍一下简单工厂模式,这样由浅入深来介绍. 简单工厂模式 做法:创建一个工厂(方法或类 ...

  4. Cisco学习记录(二):路由及网络设备配置

    本篇我们利用cisco packet tracer搭建一个简单的网络.我们在左下方的设备中尝试选择创建两个4321路由器和一个3560-24PS Multilayer交换机,然后在左下方的电缆线中选择 ...

  5. 1、WIN2D学习记录(win2d实现JS雨天效果)

    一.Win2D Win2D是微软开源的项目 它的github地址是 https://github.com/Microsoft/Win2D 里面有详细的文档 http://microsoft.githu ...

  6. LESS 学习记录(简单入门)

    什么是 LESS LESS是一种动态样式语言,属于 CSS 预处理语言的一种.它使用类似 CSS 的语法,但是 赋予了动态语言的特性,比如变量.继承.运算.函数等,方便 CSS 的编写和维护. 使用 ...

  7. WebApi官网学习记录---web api中的路由

    如果一条路由匹配,WebAPI选择controller和action通过如下方式: 1.找到controller,将"controller"赋值给{controller}变量 2. ...

  8. 最简单的原生js和jquery插件封装

    最近在开发过程中用别人的插件有问题,所以研究了一下,怎么封装自己的插件. 如果是制作jquery插件的话.就将下面的extend方法换成  $.extend 方法,其他都一样. 总结一下实现原理: 将 ...

  9. 最近老是有兄弟问我,Vue双向绑定的原理,以及简单的原生js写出来实现,我就来一个最简单的双向绑定,原生十行代码让你看懂原理

    废话不多说直接看效果图 代码很好理解,但是在看代码之前需要知道Vue双向绑定的原理其实就是基于Object.defineProperty 实现的双向绑定 官方传送门 这里我们用官方的话来说Object ...

随机推荐

  1. 【sklearn】数据预处理 sklearn.preprocessing

    数据预处理 标准化 (Standardization) 规范化(Normalization) 二值化 分类特征编码 推定缺失数据 生成多项式特征 定制转换器 1. 标准化Standardization ...

  2. Flask开发微电影网站(六)

    1. 后台管理登录功能实现 1.1 后台管理页面登录表单LoginForm 在app的admin目录下创建forms.py文件,用来保存admin蓝图中需要使用到的表单 from flask_wtf ...

  3. Token令牌管理权限

    什么是token HTTP是一种无状态的协议,也就是HTTP没法保存客户端的信息,没办法区分每次请求的不同. Token是服务器生成的一串字符,作为客户端请求的令牌.当第一次登陆后,服务器会分发Ton ...

  4. php的参数函数与可变参

    在php5.5及更早的版本中,使用func_num_args(), func_get_arg(), func_get_args()函数实现. <?php function myfunc(){ / ...

  5. 如何新建PDF文档,新建PDF文档的方法

    新建PDF文件的话,有两种方式,一种是直接通过使用PDF编辑器http://bianji.xjpdf.com/来新建PDF文件,,还有一种就是将PDF文件转换成Word文件,然后在Word文件中添加, ...

  6. 在Pythonfor循环中如何获取循环次数?

    在Python的for循环里,循环遍历可以写成: for item in list: print item 它可以遍历列表中的所有元素,但是有什么方法可以知道到目前为止我循环了多少次? 想到的替代方案 ...

  7. Linux查看当前目录下所有子目录是否包含某个文件

    在Linux下,当需要找某个文件但又不知道这个文件在哪个具体的目录下,这时可以使用全目录查找 使用find命令: find . -type f -name "job_21_output*&q ...

  8. react组件生命周期

    1. Mounting/组建挂载相关 (1)componentWillMount 组件将要挂载.在render之前执行,但仅执行一次,即使多次重复渲染该组件或者改变了组件的state (2)compo ...

  9. SparkCore | Rdd| 广播变量和累加器

    Spark中三大数据结构:RDD:  广播变量: 分布式只读共享变量: 累加器:分布式只写共享变量: 线程和进程之间 1.RDD中的函数传递 自己定义一些RDD的操作,那么此时需要主要的是,初始化工作 ...

  10. 关于jmeter读取CSV文件的详细设置

    jmeter 读取excel数据使用的方法是使用Jmeter CSV Data Set Config参数化 但是将excel文件保存成csv格式后,jmeter读取后返回的数据总是出现乱码问题, 以下 ...