JavaScript不刷新实现浏览器的前进后退功能

最近在学习backbone,学习理解backbone就要先理解spa,理解spa就要先了解单页面应用是如何做到页面不刷新改变url的。

相较于不同页面的跳转,AJAX可以说大大提高了用户的浏览体验,不用看到页面切换之间的白屏是件很惬意的事情。但是很多早先的AJAX应用是不支持浏览器的前进后退的,这导致了用户不管在网站里浏览到何处,一旦刷新就会立刻回到起初的位置,并且用户也无法通过浏览器的前进后退按钮来实现浏览历史的切换。

对于第一个问题,解决还算容易,只要用cookie或者localStorage来记录应用的状态即可,刷新页面时读取一下这个状态,然后发送相应ajax请求来改变页面即可。但是第二个问题就很麻烦了,先说下现代浏览器的解决方案。

HTML5 解决方案

要了解HTML5如何实现前进后退,就要先了解下history对象和location对象。

history对象

History 对象属性

1.length:返回浏览器历史列表中的URL数量,用户在当前标签每访问一个页面,此数量加1。因为隐私原因,URL具体内容不可见。
2.state:与当前网址相关的对象,只能通过pushState和replaceState添加或修改。我们可以可以用它来存储跟url有关的信息。

History 对象方法

1.history.back()

此方法无参数,触发后会返回前一个浏览的页面,相当于点击了浏览器的后退按钮。

2.history.forward()

此方法无参数,触发后会返回后退前浏览的页面,相当于点击了浏览器的前进按钮。

3.history.go(number)

此方法接受一个整形变量参数,history.go(-1)相当于后退一页,history.go(1)相当于前进一页,history.go(0)会刷新当前页面。

4.history.pushState(state, title, url)

改变url且不刷新页面的关键就是它了,此方法会改变当前页面的location.href并且修改当前的history.state对象,执行后history.length会增加1。此方法接受三个参数,

1.state:当前网址相关的对象。
2.title:页面标题,但是所有浏览器都忽略它,要改变标题还是要用document.title。
3.url:一个与当前页面同域的网址,location.href会变成此值。

5.history.replaceState(state, title, url)

此方法同上,但是它不会改变history.length,只会修改当history.state和location.href。

注意pushState和replaceState第三个参数不可跨域,并且不会触发浏览器的popstate事件和onhashchange事件(chrome33下测试)。

location对象

除了点击前进/后退按钮和history事件,还可以通过location的方法和修改location的属性来改变Url:

location对象的属性(读写):

1.host:域名+端口号
2.hostname:域名
3.port:端口号
4.protocol:协议
5.href:完整路径
6.origin:协议+域名+端口
7.hash:井号 (#) 开始的 URL(hash)
8.pathname:文档路径+文档名
9.search:(?)后面的内容

可以通过改变location.href或location.hash来达到无刷新的目的。

location对象的方法:

1.assign:改变url的值,并且将当前的url添加到历史记录中history.length会增加1。location.assig(‘#' + x)会改变url但是不刷新页面。
2.reload:刷新页面。
3.replace:改变url的值,但是history.length不变。使用方法同assign。

popstate事件

当url改变时,比如用户点击前进/后退按钮,history.go(n)(n不等于0),location.hash = x(x不等于当前的location.hash)都会触发此事件。可以用它来监听url,来实现各种功能。

代码如下:

window.onpopstate = function(){
        //do sth
    }

onhashchange事件

改变hash值会触发popstate事件,而触发popstate事件不一定会触发onhashchange事件。经过测试:

1.hash改变但是location.pathname不变会触发onhashchange事件,比如history.pushState(”, ”, ‘#abc');
2.hash和location.pathname一起改变则不触发,比如history.pushState(”, ”, ‘a#abc');

老旧浏览器的写法

老旧浏览器也不支持pushState和replaceState,所以通过popstate(事实上也不支持这个方法)监听url变化的路走不通。那么只能通过改变url#后面的内容来达到无刷新,但是它们又不支持onhashchange,所以对url的变化是无动于衷的(除了页面会滚动至页面对应id的位置)。那么只能祭出大招:轮询,起一个setInterval来监听url的值。Like this:

代码如下:

var prevHash = window.location.hash;
var callback = function(){...}
window.setInterval(function() {
    if (window.location.hash != prevHash) {
        prevHash = window.location.hash;
        callback(prevHash);
    }
}, 100);

当然这样写非常非常挫,如果不考虑点击页面带有id的a标签来改变hash的情况,可以利用设计模式来优雅的实现监听url。比如经典的观察者模式,专门用一个类来实现改变hash的功能,然后所有要监听url变化的类(观察者)去订阅这个(被观察者)类。

代码如下:

//改变url的类
function UrlChanger() {
    var _this = this;
    this.observers = [];
    //添加观察者
    this.addObserver = function(obj) {...}
    //删除观察者
    this.deleteObserver = function(obj) {...}
    //通知观察者
    this._notifyObservers = function() {
        var length = _this.observers.length;
        console.log(length)
        for(var i = 0; i < length; i++) {
            _this.observers[i].update();
        }
    }
    //改变url
    this.changeUrl = function(hash) {
        window.location.hash = hash;
    _this._notifyObservers();
    }
}
//监听类
function oneOfObservers() {
    var _this = this;
    this.update = function() {...}
}
//实现
var o1 = new UrlChanger();
var o2 = new oneOfObservers();
o1.addObserver(o2);
o1.changeUrl('fun/arg1/arg2/');
//o2 has do sth...

(0)

相关推荐

  • javascript下阻止表单重复提交、防刷新、防后退

    1 服务器端的解决方法.这是我最为推荐的方法.优点是判断准确,兼容性最大. 做法:a页面显示表单,然后提交b页面处理,处理完后重定向到c页面显示结果. 1.0 在访问a页面时在session里生成一个标志ID,例如 //伪代码  session("submitID")=random()  然后把这个值写到表单的一个hidden的input里 //伪代码  <%response.write("<input name=submitID2 type=hidden val

  • javascript中的后退和刷新实现方法

    <input type=button value=刷新 onclick="window.location.reload()"> <input type=button value=前进 onclick="window.history.Go(1)"> <input type=button value=后退 onclick="window.history.go(-1)"> <input type=button

  • javascript 防止刷新,后退,关闭

    复制代码 代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head> <title> New Document </title> </head> <script language="javascript"> function RunOnBeforeUnload() {window.

  • js禁止页面刷新与后退的方法

    本文实例讲述了js禁止页面刷新与后退的方法.分享给大家供大家参考.具体实现方法如下: <script language="javascript"> //禁止用F5键 function document.onkeydown() { if ( event.keyCode==116) { event.keyCode = 0; event.cancelBubble = true; return false; } } //禁止右键弹出菜单 function document.onco

  • JavaScript不刷新实现浏览器的前进后退功能

    最近在学习backbone,学习理解backbone就要先理解spa,理解spa就要先了解单页面应用是如何做到页面不刷新改变url的. 相较于不同页面的跳转,AJAX可以说大大提高了用户的浏览体验,不用看到页面切换之间的白屏是件很惬意的事情.但是很多早先的AJAX应用是不支持浏览器的前进后退的,这导致了用户不管在网站里浏览到何处,一旦刷新就会立刻回到起初的位置,并且用户也无法通过浏览器的前进后退按钮来实现浏览历史的切换. 对于第一个问题,解决还算容易,只要用cookie或者localStorag

  • Vue 禁用浏览器的前进后退操作

    一.禁用前进后退功能 在开发vue应用中,如何禁用浏览器的前进后退功能呢? 网上搜到的答案基本如下: history.pushState(null, null, document.URL) window.addEventListener('popstate', function() { history.pushState(null, null, document.URL) }) 但应该放在哪儿? 经过尝试,我是如此写的: main.js中,增加popstate监听 window.addEvent

  • 如何让浏览器支持jquery ajax load 前进、后退功能

    一般在做 ajax load 的时候,很多人都不会考虑到需要浏览器支持前进后退功能,因为大部分人都不知道可以实现. 最近遇到这个问题,经过一小段研究,发现github已经有现成的开源工具使用,主要实现原理是利用html的锚点,即<a href="#xxx"> 主要demo代码如下: html 复制代码 代码如下: <ul> <li><a href="#ttt">ttttttttttttttt</a><

  • JavaScript中防止微信浏览器被整体拖动的方法

    在微信网页开发中,我使用的页面结构是在body下的container覆盖全屏,container下有个header和page的容器,page负责显示所有内容并实现滚动. 结构如图: 但是遇到了一个问题:在页面已经滚动到顶部时,继续往下拖动page容器,会将微信浏览器整体往下拖,漏出"该网页由XXX提供"的提示,然后在安卓下,影响并不大,但是在iphone下,就没那么简单了,经过测试,在苹果下,往下拖动后快速滑动页面中的page,page并不会滚动,上拖同样遇到了这个问题,非常影响体验.

  • js禁止浏览器页面后退功能的实例(推荐)

    实例如下所示: <script> $(function(){ if(window.location.href.indexOf("/login") > -1) { //防止页面后退 history.pushState(null, null, document.URL); window.addEventListener('popstate', function () { history.pushState(null, null, document.URL); }); }

  • javascript学习随笔(编写浏览器脚本 Navigator Scripting )

    在 HTML 中使用JavaScript JavaScript能以两种方式嵌入HTML: 作为语句和函数使用时,用 SCRIPT 标记 作为事件处理程序使用时,用 HTML 标记 SCRIPT 标记 使用SCRIPT标记把脚本嵌入在HTML中,格式如舷: <SCRIPT> _ JavaScript 语句</SCRIPT> LANGUAGE属性作为可选项,用于指定脚本语言,用法如下: <SCRIPT LANGUAGE="JavaScript"> _Ja

  • javascript无刷新评论实现方法

    本文实例讲述了javascript无刷新评论实现方法.分享给大家供大家参考.具体实现方法如下: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无刷新评论</title> <s

  • JavaScript遍历Json串浏览器输出的结果不统一问题

    没有介绍正文之前先给大家说下json是什么. JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,我们称之为JavaScript对象表示法.使用JSON进行数据传输的优势之一是JSON实际上就是JavaScript.它基于ECMAScript第3版中JavaScript对象字面量语法子集的一种文本格式.这表示可以使用responseText从服务器中检索JSON数据,然后再使用JavaScript的eval()方法将JSON字符串转换成JavaScrip

  • JavaScript实现刷新不重记的倒计时

    前言 JavaScript倒计时,实现起来不难,但是一刷新往往就重新计算了,如果要实现刷新不重计该如何做呢? 有这么几种思路, 1:cookie 2:本地缓存 3:window.name -- 前两种比较容易理解,今天我来为大家实现使用window.name实现刷新不重计,代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DT

  • JavaScript中解决多浏览器兼容性23个问题的快速解决方法

    一.document.formName.item("itemName") 问题 问题说明:IE下,可以使用 document.formName.item("itemName") 或 document.formName.elements ["elementName"]:Firefox 下,只能使用document.formName.elements["elementName"]. 解决方法:统一使用document.formNa

随机推荐