还记得jquery时代吗,那时前端三大框架还没流行,前端开发者疯狂查着jquery的API文档来进行dom操做,还记得这个地址吗 jquery.cuishifeng.cn/ 是否是颇有感受!(想了解前端历史的,请看我这篇文章前端技术发展 juejin.im/post/5cc6b5…javascript
记得在学校里刚开始写网页的时候,只是对JavaScript学了个大概,而后就开始学jquery进行网页开发了。css
若是你曾经也是jquery开发者,看到这块代码时,杯中的水开始颤抖,啊!个人青春啊!html
那时毕业后的大半年写前端就只用了 jquery ,没有如今这些前端框架提供的工程化,模块化,组件化(其实有,但我还没学没用,并且我进的第一个公司那时我是公司的第一个前端,没有前辈的教导,本身摸索)。写前端就用了js(jquery),css,html,来进行项目的工程文件目录结构搭建。想一想那段日子可真累啊!前端
那时写网页时遇到个需求:java
假设一个页面左侧是若干导航连接,右侧是内容,同时导航时只有右侧的内容须要更新,那么刷新整个页面无疑是浪费的(本来每一个导航连接都是a标签href跳转网页)。这时咱们可使用 AJAX 来拉取右面的数据。可是若是仅仅这样,地址栏是不会改变的,用户没法前进、后退,也没法收藏当前页面或者把当前页面分享给他人;搜索引擎抓取也有困难。jquery
这时,查到 HTML5 的 History API 就能够解决这个问题。web
思路:数据库
首先绑定click事件。当用户点击一个连接时,经过preventDefault函数防止默认的行为(页面跳转),同时读取连接的地址(若是有jQuery,能够写成 $(this).attr('href')),把这个地址经过pushState塞入浏览器历史记录中,再利用 AJAX 技术拉取(若是有 jQuery,可使用$.get方法)
这个地址中真正的内容,同时替换当前网页的内容。后端
为了处理用户前进、后退,咱们监听popstate事件。当用户点击前进或后退按钮时,浏览器地址自动被转换成相应的地址,同时popstate事件发生。在事件处理函数中,咱们根据当前的地址抓取相应的内容,而后利用 AJAX 拉取这个地址的真正内容,呈现,便可。设计模式
最后,整个过程是不会改变页面标题的,能够经过直接对document.title赋值来更改页面标题。
代码相似于这样:
window.history.pushState(null, null, "/profile/");
复制代码
这套 API 提供一种「人为操纵」浏览器历史记录的方法。
浏览器历史记录能够看做一个「栈」。栈是一种后进先出的结构,能够把它想象成一摞盘子,用户每点开一个新网页,都会在上面加一个新盘子,叫「入栈」。用户每次点击「后退」按钮都会取走最上面的那个盘子,叫作「出栈」。而每次浏览器显示的天然是最顶端的盘子的内容。
var state = {
id: 2,
name: "profile"
};
window.history.pushState(state, "My Profile", "/profile/");
// 它能够接收三个参数,按顺序分别为:
// 1.一个对象或者字符串,用于描述新记录的一些特性。这个参数会被一并添加到历史记录中,以供之后使用。这个参数是开发者根据本身的须要自由给出的。
// 2.一个字符串,表明新页面的标题。当前基本上全部浏览器都会忽略这个参数。
// 3.一个字符串,表明新页面的相对地址。
复制代码
当用户点击浏览器的「前进」、「后退」按钮时,就会触发popstate事件。你能够监听这一事件,从而做出反应。
window.addEventListener("popstate", function(e) {
var state = e.state;
// do something...
});
// 这里e.state就是当初pushState时传入的第一个参数。例如,在咱们的例子中,有:
// e.state.id == 2;
// e.state.name == "profile";
复制代码
有时,你但愿不添加一个新记录,而是替换当前的记录(好比对网站的 landing page),则可使用replaceState方法。这个方法和pushState的参数彻底同样。
hash也是一种改变浏览器url而不会刷新页面的方案
“#”表明网页中的一个位置。其右面的字符,就是该位置的标识符
浏览器读取这个URL后,会自动滚动至comment评论位置区域。
为网页位置指定标识符,有两个方法。
<a name="comment"></a>
复制代码
<div id="comment"></div>
复制代码
因此当咱们使用的时候不指定标识符,网页就不会定位,但又能获得咱们想要的改变浏览器url而不会刷新页面
‘#’是用来指导浏览器动做的,对服务器端彻底无用。因此,HTTP请求中不包括#。
好比,访问下面的网址, juejin.im/post/5dc664… 咱们打开F12查看network的all,看第一条,咱们发现并无#comment这部分数据传参
history是浏览器的历史记录,location是浏览器当前url信息(hash就是其中的值),他们都是浏览器BOM提供的api
这是一个HTML 5新增的事件,当#值发生变化时,就会触发这个事件。
function hashHandler() {
console.log('The hash has changed!');
}
window.addEventListener('hashchange', hashHandler, false);
复制代码
这块内容都是找的网上的文章,网上资料不少,学习了两篇 juejin.im/post/5d469f… juejin.im/post/5d2d19…
路由的概念起源于服务端,在之前先后端不分离的时候,由后端来控制路由,当接收到客户端发来的 HTTP 请求,就会根据所请求的相应 URL,来找到相应的映射函数,而后执行该函数,并将函数的返回值发送给客户端。对于最简单的静态资源服务器,能够认为,全部 URL 的映射函数就是一个文件读取操做。对于动态资源,映射函数多是一个数据库读取操做,也多是进行一些数据的处理等等。而后根据这些读取的数据,在服务器端就使用相应的模板来对页面进行渲染后,再返回渲染完毕的页面。它的好处与缺点很是明显:
也正是因为后端路由还存在着本身的不足,前端路由才有了本身的发展空间。对于前端路由来讲,路由的映射函数一般是进行一些 DOM 的显示和隐藏操做。这样,当访问不一样的路径的时候,会显示不一样的页面组件。
SPA 是 single page web application 的简称,译为单页Web应用。
简单的说 SPA 就是一个WEB项目只有一个 HTML 页面,一旦页面加载完成,SPA 不会由于用户的操做而进行页面的从新加载或跳转。 取而代之的是利用 JS 动态的变换 HTML 的内容,从而来模拟多个视图间跳转。
前端路由不是什么新技术,咱们只是使用了后端使用的路由这个名称,其实他就是对浏览器的hash模型和history模式的封装(各个前端框架都封装了各自的路由,咱们查阅文档按照规则规范使用就行)。
因此当咱们知道浏览器的hash和history后就能明白一些以前咱们以为神奇的地方。
咱们不造轮子,但咱们得知道这个轮子出来的目的及意义,基于什么原理。若是你对这个轮子很感兴趣,那你能够阅读源码,学习里面的代码思路,设计模式,但不要鉴于已有的东西再造一个,没有意义。
若是你想了解一些路由的简单封装,点击前面贴出的两篇文章地址,学习一下。深刻学习请看三大框架路由源码,自行摸索。