HTML5新特性【pushState】和【replaceSt
近来在处理浏览器禁刷功能时,用到一个新属性:history.pushState();
官方解释如下:
history.pushState()方法和history.replaceState()方法,它们允许你逐条地添加和修改历史记录条目。这些方法可以协同window.onpopstate事件一起工作。
使用 history.pushState() 会改变 referrer 的值,而在你调用方法后创建的XMLHttpRequest对象会在 HTTP 请求头中使用这个值。referrer的值则是创建XMLHttpRequest对象时所处的窗口的URL。
首先附上一个实例功能:
//防止浏览器后退功能$(document).ready(function(e){varurl=window.location.href;varlast=url.substring(url.lastIndexOf("/"));if(window.history&&window.history.pushState){$(window).on('popstate',function(){//在IE中必须得有这两行window.history.pushState('forward',null,url);window.history.forward(1);});}//屏蔽鼠标右键$(document).bind("contextmenu",function(e){returnfalse;});//屏蔽f5和回车功能$(document).bind("keydown",function(e){if(event.keyCode==116){event.keyCode=0;event.cancelBubble=true;returnfalse;}});});
以及附上【pushState】和【replaceState】的基础语法区别:
history.pushState(state, title, url)
将当前URL和history.state加入到history中,并用新的state和URL替换当前。
不会造成页面刷新。
state:与要跳转到的URL对应的状态信息。
title:可以不传
url:要跳转到的URL地址,不能跨域。
history.replaceState(state, title, url)
用新的state和URL替换当前。
不会造成页面刷新。
state:与要跳转到的URL对应的状态信息。
title:可以不传
url:要跳转到的URL地址,不能跨域。
最大区别则在于:
pushState是添加历史记录的,而replaceState是不添加的。
接下来开始讲解两者之间的语法分析:
1、实例
假设http://mozilla.org/foo.html将执行如下JavaScript代码:
varstateObj={foo:"bar"};history.pushState(stateObj,"page2","bar.html");
这将让浏览器的地址栏显示http://mozilla.org/bar.html,但不会加载bar.html页面也不会检查bar.html是否存在。
假设现在用户导航到了http://google.com,然后点击了后退按钮,此时,地址栏将会显示http://mozilla.org/bar.html,并且页面会触发popstate事件,该事件中的状态对象(state object)包含stateObj的一个拷贝。该页面看起来像foo.html,尽管页面内容可能在popstate事件中被修改。
如果我们再次点击后退按钮,URL将变回http://mozilla.org/foo.html,文档将触发另一个popstate事件,这次的状态对象为null。回退同样不会改变文档内容。
2、pushState()方法:添加和修改历史记录条目
①语法:
history.pushState(state,title,url);
pushState()有三个参数:一个状态对象、一个标题(现在会被忽略),一个可选的URL地址。下面来单独考察这三个参数的细节:
状态对象(state object)— 一个JavaScript对象,与用pushState()方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态,popstate事件都会被触发,并且事件对象的state属性都包含历史记录条目的状态对象的拷贝。
任何可序列化的对象都可以被当做状态对象。因为FireFox浏览器会把状态对象保存到用户的硬盘,这样它们就能在用户重启浏览器之后被还原,我们强行限制状态对象的大小为640k。如果你向pushState()方法传递了一个超过该限额的状态对象,该方法会抛出异常。如果你需要存储很大的数据,建议使用sessionStorage或localStorage。
标题(title)— FireFox浏览器目前会忽略该参数,虽然以后可能会用上。考虑到未来可能会对该方法进行修改,传一个空字符串会比较安全。或者,你也可以传入一个简短的标题,标明将要进入的状态。
地址(URL)— 新的历史记录条目的地址。浏览器不会在调用pushState()方法后加载该地址,但之后,可能会试图加载,例如用户重启浏览器。新的URL不一定是绝对路径;如果是相对路径,它将以当前URL为基准;传入的URL与当前URL应该是同源的,否则,pushState()会抛出异常。该参数是可选的;不指定的话则为文档当前URL。
②样例
创建了一个新的由state,title, 和url设定的浏览器历史纪录.
varstate={'page_id':1,'user_id':5};vartitle='HelloWorld';varurl='hello-world.html';history.pushState(state,title,url);
③优势
某种意义上,调用pushState()有点类似于设置window.location='#foo',它们都会在当前文档内创建和激活新的历史记录条目。但pushState()有自己的优势:
新的URL可以是任意的同源URL,与此相反,使用window.location方法时,只有仅修改 hash 才能保证停留在相同的document中。
根据个人需要来决定是否修改URL。相反,设置window.location='#foo',只有在当前hash值不是foo时才创建一条新历史记录。
你可以在新的历史记录条目中添加抽象数据。如果使用基于hash的方法,你只能把相关数据转码成一个很短的字符串。
注意:pushState()方法永远不会触发hashchange事件,即便新的地址只变更了hash。
3、replaceState()方法:修改浏览器当前历史记录条目
history.replaceState()操作类似于history.pushState(),不同之处在于replaceState()方法会修改当前历史记录条目而并非创建新的条目。
当你为了响应用户的某些操作,而要更新当前历史记录条目的状态对象或URL时,使用replaceState()方法会特别合适。
4、popstate事件
每当激活的历史记录发生变化时,都会触发popstate事件。如果被激活的历史记录条目是由pushState所创建,或是被replaceState方法影响到的,popstate事件的状态属性将包含历史记录的状态对象的一个拷贝。
调用history.pushState()或者history.replaceState()不会触发popstate事件.popstate事件只会在其他浏览器操作时触发, 比如点击后退按钮(或者在JavaScript中调用history.back()方法).
当网页加载时,各浏览器对popstate事件是否触发有不同的表现,Chrome 和 Safari会触发popstate事件, 而Firefox不会.
①语法
window.onpopstate=funcRef;
funcRef是个函数名.
②实例
假如当前网页地址为http://example.com/example.html,则运行下述代码后:
window.onpopstate=function(event){alert("location:"+document.location+",state:"+JSON.stringify(event.state));};//绑定事件处理函数.history.pushState({page:1},"title1","?page=1");//添加并激活一个历史记录条目http://example.com/example.html?page=1,条目索引为1history.pushState({page:2},"title2","?page=2");//添加并激活一个历史记录条目http://example.com/example.html?page=2,条目索引为2history.replaceState({page:3},"title3","?page=3");//修改当前激活的历史记录条目http://ex..?page=2变为http://ex..?page=3,条目索引为3history.back();//弹出"location:http://example.com/example.html?page=1,state:{"page":1}"history.back();//弹出"location:http://example.com/example.html,state:nullhistory.go(2);//弹出"location:http://example.com/example.html?page=3,state:{"page":3}
即便进入了那些非pushState和replaceState方法作用过的(比如http://example.com/example.html)没有state对象关联的那些网页,popstate事件也仍然会被触发.
5、读取当前状态
在页面加载时,可能会包含一个非空的状态对象。这种情况是会发生的,例如,如果页面中使用pushState()或replaceState()方法设置了一个状态对象,然后用户重启了浏览器。当页面重新加载时,页面会触发onload事件,但不会触发popstate事件。但是,如果你读取history.state属性,你会得到一个与popstate 事件触发时得到的一样的状态对象。
你可以直接读取当前历史记录条目的状态,而不需要等待popstate事件:
varcurrentState=history.state;
6、浏览器兼容性
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。