您的位置:首页 > Web前端 > JavaScript

实现不刷新整个页面进行前进后退

2017-10-10 19:11 302 查看
在html5出来前,实现无刷新前进后退通常是结合location.hash+onhashchange事件来实现的;

在html5出来后,可以使用h5 history api来实现无刷新前进后退

点击浏览器的前进后退按钮时,只要将要进入的页面与当前页面不是同一个页面(因为有可能人为地添加了一条历史记录,但实际上还是同一个页面),那么将要进入的页面其所有请求(包括html、js、css、json和图片等)都是直接从缓存里读取的(除非禁用了缓存),但js还是会重新执行一遍。如果该页面是用ajax获取数据的,那么不管前进或者后退到该页面时,都会重新ajax请求数据。

HTML5中history那些事

SEPTEMBER 26TH, 2015

HTML5中History对象提供了两个新的方法,pushState和replaceState用来在无刷新页面情况下更改url,为单页应用提供了很大方便,但是在使用时需要注意一些事情。

原来有什么

History对象原来有三个方法,一个属性。

history.length:历史列表中的网址数。

history.back():加载历史列表前一个网址。

history.forward():加载历史列表后一个网址。

history.go(num):加载历史列表中的某个页面,参数为相对当前页面,跳转的次数。go(-1)与back()效果相同,go(1)与forward()效果相同。go(-2)与单击两次后退按钮执行的操作一样。

新增了什么

History对象新增了两个方法,一个属性,新增了一个事件。

history.pushState(state,title,url):替换url为当前url并添加历史记录,title为历史记录的title,state为一个用户存储的对象,可以通过history.state或window.onpopstate事件的event.state访问。

history.replaceState(state,title,url):参数与history.pushState相同,不同点在于该方法更改当前历史记录,不会产生新的历史记录。

history.state:用户存储的对象。

window.onpopstate:当使用history.pushState或history.replaceState控制历史记录后,触发浏览器的前进/回退操作会触发该事件。

注意事项

state属性不能通过history.state或window.onpopstate的event.state来修改,只能通过history.pushState或history.replaceState修改。

state属性必须是可序列化的值,如DOM对象不可设置。

history.state与window.onpopstate的event.state不相等。

history.pushState与history.replaceState的url参数与网站url必须是同域的,否则会出现跨域错误。需要注意,当history.pushState或history.replaceState的url参数为/abc/def或abc/def时所使用的origin为加载该<script>的origin,如果操作History的是外部js文件,请拼接上location.origin。

还差什么

当前在哪

History没有提供获取当前页面在历史列表位置的方法,这个属性作用不大,只有在单页应用,且拥有非顺序跳转逻辑时才会用到,既然系统不提供,只能自己推算。

首先要保证每个页面设置state属性,这样可以通过该属性判断是否是已经加载过页面。 当首次加载应用时,检查history.state属性,如果该属性未设置,那么必然为新开页面,此时必然为历史列表第一个,当使用history.pushState后,逻辑同上。,此两种情况current为history.length。其余情况即为页面跳转或当前页面刷新,current即为之之前两种情况保存的值。

HTML4中的History API

属性

length 历史的项数。javascript 所能管到的历史被限制在用浏览器的“前进”“后退”键可以去到的范围。本属性返回的是“前进”和“后退”两个按键之下包含的地址数的和。

方法

back() 后退,跟按下“后退”键是等效的。

forward() 前进,跟按下“前进”键是等效的。

go() 用法:history.go(x);在历史的范围内去到指定的一个地址。如果 x < 0,则后退 x 个地址,如果 x > 0,则前进 x 个地址,如果 x == 0,则刷新现在打开的网页。history.go(0) 跟 location.reload()
是等效的。

HTML5中的History API(使用h5的history api可以不用更改页面url的hash值)

操纵浏览器的历史记录

1. history.pushState(data, title [, url]):往历史记录堆栈顶部添加一条记录;data会在onpopstate事件触发时作为参数传递过去;title为页面标题,当前所有浏览器都会 忽略此参数;url为页面地址,可选,缺省为当前页地址。

2. history.replaceState(data, title [, url]) :更改当前的历史记录,参数同上。

3. history.state:获取历史栈中最顶端的state数据(即history.pushState中的第一个参数),不同浏览器的读写权限不一样。

4. popstate事件:当用户单击浏览器的后退或者前进按钮(或者调用history.go,history.back,history.forward方法也会触发popstate事件。调用history.pushState()或者history.replaceState()不会触发popstate事件,但改变url中的hash值会触发popstate事件)时触发该事件。在事件处理函数中读取触发事件的事件对象的state属性值,该属性值即为执行pushState方法时所使用的第一个参数值,该state与history.state是相同的,而不是历史栈中被抛出的state对象。

到目前为止,IE10,firefox4以上的版本,Chrome8以上的版本,Safari5,Opera11以上的版本浏览器支持HTML5中的History API。

判断是否支持h5 history api:

if ('pushState' in history) { ... };

h5 history api实现无刷新跳转

使用location.hash+onhashchange实现无刷新跳转

原理:改变url中#后面的值会创建一条历史记录(但不会刷新整个页面)并会触发onhashchange事件。监听此事件并通过window.location.hash获取url中 "#val" 的值。根据不同的"#val" 来触发页面不同的操作,显示对应内容。

JS刷新页面

1,reload 方法,该方法强迫浏览器刷新当前页面。

语法:location.reload([bForceGet])

参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当前页。true, 则以 GET 方式,从服务端取最新的页面, 相当于客户端点击 F5("刷新")

2,replace 方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,你不能通过“前进”和“后退”来访问已经被替换的URL。

语法: location.replace(URL)

通常使用: location.reload() 或者是 history.go(0) 来做。

此方法类似客户端点F5刷新页面,所以页面method="post"时,会出现"网页过期"的提示。

因为Session的安全保护机制。

当调用 location.reload() 方法时, aspx页面此时在服务端内存里已经存在, 因此必定是 IsPostback 的。

如果有这种应用: 需要重新加载该页面,也就是说期望页面能够在服务端重新被创建,期望是 Not IsPostback 的。

这里,location.replace() 就可以完成此任务。被replace的页面每次都在服务端重新生成。

代码: location.replace(location.href);

返回并刷新页面:

location.replace(document.referrer);

document.referrer //打开当前页面的文档的URL

这种方法并不是返回到上一个历史记录,而是将当前的记录替换为document.referrer,导致history中有重复的两个document.referrer记录

不要用 history.go(-1),或 history.back();来返回并刷新页面,这两种方法不会刷新页面,而是直接从浏览器缓存里获取内容(除非禁用了缓存)。

Javascript刷新页面(即重新从服务器下载页面)的几种方法:

F5和CTRL+F5的区别

以下都是在chrome下测试的

1,history.go(0)

跟按F5一样,无法跳过浏览器缓存。F5触发的所有HTTP请求的请求头中通常包含了If-Modified-Since
或 If-None-Match字段,或者两者兼有.如果服务器认为被请求的文件没有发生变化,则返回304响应,浏览器直接从缓存中获取.

注意点:上述情况只适用于第一次请求时响应头中携带Last-Modified或者ETag字段的请求,如果第一次请求时响应头中没有携带这些字段,而是携带的Transfer-Encoding:chunked(分块传输),那么再次发起该请求时,请求头里不会携带If-Modified-Since
或 If-None-Match字段,会从服务器重新下载文件

CTRL+F5触发的HTTP请求的请求头中没有上面的那两个头(所有的请求都是从服务器重新获取数据),却有Pragma:
no-cache 或 Cache-Control: no-cache 字段,或者两者兼有.服务器看到no-cache这样的值就会把最新的文件响应过去.也就跳过了缓存.

2,location.reload()

3,location=location

4,location.assign(location)

5,document.execCommand('Refresh')

6,window.navigate(location)

7,location.replace(location)

8,document.URL=location.href

来源网址:http://www.qdfuns.com/notes/17631/ff37e5968e6592847e05c14ce754c917.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript web前端