HTML5为history对象添加了两个新方法,history.pushState()和history.replaceState(),用来在浏览历史中添加和修改记录。

都会改变浏览器标签栏中的URL值,区别在于pushState()会将之前的地址记录在history对象中,通过back()可以返回前一页,replaceState()则不能返回 
我用到的是history.replaceState()

接收三个参数

var shortURL=top.location.href.substring(0,top.location.href.indexOf('?')); 
history.replaceState(null,null,shortURL)

转自 : http://www.cnblogs.com/shytong/p/5378510.html

一、Pjax

  像Github、百度、微博等这些大站,已经不再使用普通的a标签做跳转了。他们大多使用Ajax请求替代了a标签的默认跳转,然后使用HTML5的新API修改了Url,你可以在F12的Network面板里发现这个秘密。
这项技术并没有特别标准的学名,大家都称呼为Pjax,意为PushState + Ajax。这并不完全准确,因为还有Hash + Ajax等方法,但为了方便,我们下文还是统称为Pjax。

为什么要这么做?

Pjax是一个优秀的解决方案,你有足够多的理由来使用它:

  • 可以在页面切换间平滑过渡,增加Loading动画。
  • 可以在各个页面间传递数据,不依赖URL。
  • 可以选择性的保留状态,如音乐网站,切换页面时不会停止播放歌曲。
  • 所有的标签都可以用来跳转,不仅仅是a标签。
  • 避免了公共JS的反复执行,如无需在各个页面打开时都判断是否登录过等等。
  • 减少了请求体积,节省流量,加快页面响应速度。
  • 平滑降级到低版本浏览器上,对SEO也不会有影响。

原理呢?

  Pjax的原理十分简单。 1. 拦截a标签的默认跳转动作。 2. 使用Ajax请求新页面。 3. 将返回的Html替换到页面中。 4. 使用HTML5的History API或者Url的Hash修改Url。

HTML5 History API

我们来看看HTML5在History里增加了什么:

history.pushState(state, title, url)
pushState方法会将当前的url添加到历史记录中,然后修改当前url为新url。请注意,这个方法只会修改地址栏的Url显示,但并不会发出任何请求。我们正是基于此特性来实现Pjax。它有3个参数:

  • state: 可以放任意你想放的数据,它将附加到新url上,作为该页面信息的一个补充。
  • title: 顾名思义,就是document.title。不过这个参数目前并无作用,浏览器目前会选择忽略它,传null即可。
  • url: 新url,也就是你要显示在地址栏上的url。

history.replaceState(state, title, url)
replaceState方法与pushState大同小异,区别只在于pushState会将当前url添加到历史记录,之后再修改url,而replaceState只是修改url,不添加历史记录。

window.onpopstate 事件 一般来说,每当url变动时,popstate事件都会被触发。但若是调用pushState来修改url,该事件则不会触发,因此,我们可以把它用作浏览器的前进后退事件。该事件有一个参数,就是上文pushState方法的第一个参数state。

一个实例:

这里我们以daipig为例,打开daipig,地址栏是http://www.daipig.com 。接下来打开F12 Console,输入:

history.pushState({ a: 1, b: 2 }, null, "http://www.daipig.com/abcdefg");

可以发现,url已经变成我们输入的url了,但页面并没有刷新,也没有发出任何请求。现在再输入history.state,就可以看到我们刚刚传过来的第一个参数state了。
这时点击后退,url会回到www.daipig.com,同样是没有刷新。只不过后退的时候其实是触发了window.onpopstate事件的。

详细文档可以查阅MDN: https://developer.mozilla.org/zh-CN/docs/DOM/Manipulating_the_browser_history

怎么完整的实现Pjax?

Pjax的原理上文已经讲了,并不复杂。我实现了一个比较粗糙的Pjax库,已经能满足不少需求,地址在文末。
完整的代码见Github,这里我们只谈需要注意的一些地方。

匹配选择器

要实现Pjax,难免就会有匹配选择器的需求。你需要判断当前点击的元素,是否匹配指定选择器。这里我给出一个兼容至IE8的解决方法:

// 判断element是否匹配选择器selector
function matchSelector(element, selector) {var match = document.documentElement.webkitMatchesSelector || document.documentElement.mozMatchesSelector || document.documentElement.msMatchesSelector ||// 兼容IE8及以下浏览器function(selector, element) {// 这是一个好方法,可惜IE8连indexOf都不支持// return Array.prototype.indexOf.call(document.querySelectorAll(selector), this) !== -1;if (element.tagName === selector.toUpperCase()) return true;var elements = document.querySelectorAll(selector),length = elements.length;while (length--) {if (elements[length] === this) return true;}return false;};// 重写函数自身,使用闭包keep住match函数,不用每次都判断兼容matchSelector = function(element, selector) {return match.call(element, selector);};return matchSelector(element, selector);
}
// 验证一下
matchSelector(document.getElementById("abc"), "#abc"); // true
matchSelector(document.querySelector("a"), "p"); // false

在现代浏览器上,优先使用原生的matchesSelector方法来判断,在IE8及以下的浏览器里,循环document.querySelector的结果集,依次对比。
这个方法利用了闭包,然后重写自身,只有在第一次调用时需要判断加哪个前缀执行哪个方法,其后都是调用了闭包的match函数。

不支持HTML5 PushState的浏览器怎么办?

IE6到IE9是不支持pushState的,要修改Url,只能利用Url的Hash,也即是#号。
你可以随意找个网站试一下,在url后面加上#号和任意内容,页面并不会刷新。此时点击后退也只会回到上一条#号,同样不会刷新。
那么我们只需把pushState(新url)换成localtion.hash = 新url,把onpopstate事件换成onhashchange事件就可以兼容IE了。 QQ音乐,网易云音乐等就是使用这种方式。

二、只改变 URL Hash 的单页面应用

仔细观察可以发现,现在的 Twitter,Google,Facebook 的 URL 地址充斥着 #号或者 #! 号。例如一个新版 Twitter 地址是这样的

https://twitter.com/#!/chloerei

这个 #! 号有什么意义呢?这个可以看看阮一峰整理的这篇《URL的井号》。这里假设你已经了解 # 号后面的改变不会导致页面加载,怎么利用这个特性达到 1.3 提出的目标。

第一步,有关 Ajax 调用的链接全部用 #path 作为链接目标

例如,如果一个链接本来是

<a href="/topics/1">topic1</a>

就修改为

<a href="#/topics/1">topic1</a>

显然,如果不做后续工作的话,这个链接点击后页面不会发生什么变化,用户也不会被带到新地址。唯一的改变是 URL 的 # 号部分变成了 #topics/1

设置 onhashchange 事件

在 javascript api 中,窗口 window 对象的 hash 值(# 号后面部分)发生变化时,会调用 onhashchange 事件。给 onhashchange 挂上一个 function,就可以在 hash 有改动的时候调用这个 function。

例如可以在控制台输入这段 js 代码测试

window.onhashchange = function(){alert(window.location.hash)}

实际中 function 里面就是放置真正用来刷新页面的代码了。比如在 jQuery 里用 $.get(location.path)。

效果

现在的 twitter,gooogle,facebook 都是使用这种方法刷新页面,这对浏览器书签、后退的支持也很好。

但是这有一些副作用。

一是因为页面路径被写在了 Hash 里面,而浏览器是不向服务器发送 Hash 部分的。所以打开这样的 URL 需要两个来回:1、打开空白的首页 2、根据 Hash 用 Ajax 载入实际内容

二是把路径写在了 Hash 里面破坏了 URL 原先的含义。从 URL 字面看

https://twitter.com/#!/chloerei

这个页面表示的是 twitter.com 页面上的 !/chloerie 锚点。但从实际内容上,这表示的是 chloerei 的个人页面。所以有人称这种站点为“单页面应用”。总的来说,这个方案对主流浏览器的支持程度很高,是目前的主流方案。

单页面应用的页面跳转及如何通过url跳转至指定页面相关推荐

  1. 扫描普通二维码跳转到微信小程序指定页面

    登陆微信公众平台 - 开发管理 - 开发设置 添加如下配置: 二维码规则这里写上一个自己拥有的域名,如我这里写了https://wa.al.com.cn是我的域名地址,wechat/test是我的服务 ...

  2. 实现微信扫一扫跳转到小程序指定页面

    使用微信扫一扫进入小程序内的指定页面 文章目录 使用微信扫一扫进入小程序内的指定页面 前言 一.微信小程序平台配置 二.前端uniapp中的获取二维码信息 三.后端处理参数 总结 前言 使用场景:例如 ...

  3. uni-app微信小程序生成自定义参数二维码,跳转小程序指定页面,获取参数;uni-app微信小程序获取二维码自定义参数;微信小程序生成动态参数二维码;uni-app微信小程序获取动态参数二维码;

    一.场景需求: 在小程序个人名片页面A页面,生成用户的个人名片二维码(该二维码携带用户的唯一标识id):微信扫一扫或长按图片识别这个二维码,可以跳转到小程序的B页面,并且在B页面拿到二维码上的唯一标识 ...

  4. 怎样将PDF中指定页面方向进行旋转

    我们每天工作中都会接触大量的PDF文档,有时文件打开页面方向不对阅读起来非常不方便,但调整的时候要么整个文档所有页面都被旋转,要么不能保存,是否可以只旋转指定页面的方向并保存呢? 一般用PDF阅读器查 ...

  5. 微信小程序中的html路径,新媒体运营:如何提取微信小程序路径到指定页面

    目前微信小程序的功能已经非常的完善,可能平时我们都没有留意到.现在很多的app都有小程序版本,在微信端使用及推广都很便捷. 新媒体运营的同学们可能会发现一个问题,就是怎么才能直接到达小程序的一个指定页 ...

  6. 指定页面模式,避开IE兼容性问题

    做web页面的时候,笔者喜欢用Chrome进行调试.当然Chrome下调出来的页面,跟IE的兼容性是有很大问题的.好在IE8之后,IE的兼容性问题已经有了很大的改观.由于公司做的是企业应用,可以对用户 ...

  7. URL跳转漏洞详解与实战

    URL跳转漏洞描述 服务端未对传入的跳转url变量进行检查和控制,可导致恶意用户构造一个恶意地址,诱导用户跳转到恶意网站. 跳转漏洞一般用于钓鱼攻击,通过跳转到恶意网站欺骗用户输入用户名和密码来盗取用 ...

  8. Web安全-URL跳转与钓鱼

    概述 URL跳转事件是比较常见的,比如,登陆网页以后,从登陆页面跳转到另一个页面,这就叫做URL跳转,但是URL跳转怎么和网络钓鱼联系在一起呢?下面将详细介绍URL跳转与钓鱼. URL重定向漏洞也称U ...

  9. 二级域名的URL跳转

    呵呵,最近这个问题困扰了好久了.为什么会提到这个问题呢,那是因为我的文章发到某个论坛.那边的管理员说不能带某淘的连接,各位你懂得呢. 既然不让带,那么咱们就来一个合法的二级域名,进行跳转.也就是URL ...

最新文章

  1. windows安装配置git和Tortoisegit
  2. CSS父级子级学习总结
  3. vuex ajax dev,vuex中使用ajax的话如何维护状态?
  4. html引入jquery_jQuery
  5. 四叶草社交平台——十天冲刺(4)
  6. matlab 启动图标
  7. iOS开发多线程篇---线程间的通信
  8. C# 根据EXCEL自动生成oracle建表语句
  9. HTML中空格怎么打出来?
  10. 接口工具POSTMAN怎么设置中文
  11. Laplance算子(二阶导数)
  12. 【Servlet入门】一篇文章让你从没听过到了熟于心
  13. 视频片段怎么做成gif图?快试试这2种方法
  14. 脚踏实地,不要飘忽不定
  15. fetch_array()与fetch_assoc()的用法
  16. 浏览器被恶意设置主页http://www.2345.com/?kunown的解决方法
  17. c语言程序设计上海交通大学,医学院举行“C语言程序设计”教学座谈会
  18. Oracle 数据库安装规范--database所在路径和归档目录所在路径必须分开
  19. 饥荒联机显示不了服务器,饥荒联机版启动服务器出现了一点小问题 | 手游网游页游攻略大全...
  20. 数码相机导购(Canon A75为例)

热门文章

  1. Mozilla浏览器和GUI整合第二步--消息传递
  2. mac笔记本中找不到library文件夹的解决办法
  3. Oracle数据库体系结构理论
  4. android 矢量图 开源,Android 使用 SVG 矢量图
  5. 超链接标签、注释标签
  6. 爬虫实战1-多进程爬取 名言网
  7. CSS常用尺寸单位含义总结
  8. 音乐知识讲座系列-吉他和铉
  9. 网页设计作业,网页制作作业HTML5+CSS大作业——汽车专题网页设计(1页) dreamweaver作业静态HTML网页设计模板
  10. 语法糖是什么?(ES6的一些小笔记)