开头总要有点废话html
这个功能在原先的js分享中 有简单的带过,这里拎出来 详细的讲解下原理和存在的问题(因为是运用html5的新API 因此有兼容问题,推荐移动端使用该方法)。html5
功能描述:算法
在浏览器中新建标签页并指定一个网址,网页加载完毕后,正常流程下是不容许点击返回的。由于当前标签页的相关历史记录是没有的,因此没有记录能够返回。浏览器
应客户要求,须要在这种状况下,给他的历史记录里添加一个连接(好比首页),这样在新打开的页面,点击返回就能够跳转到首页,让用户看到系统的各类功能,推广平台。安全
知识要点微信
HTML5引进了history.pushState()方法和history.replaceState()方法,它们容许你逐条地添加和修改历史记录条目。这些方法能够协同window.onpopstate事件一块儿工做。session
假设 http://mozilla.org/foo.html 将执行以下JavaScript代码:优化
1 var stateObj = { foo: "bar" }; history.pushState(stateObj, "page 2", "bar.html");
这将让浏览器的地址栏显示http://mozilla.org/bar.html,但不会加载bar.html页面也不会检查bar.html是否存在。google
假设如今用户导航到了http://google.com,而后点击了后退按钮,此时,地址栏将会显示http://mozilla.org/bar.html,而且页面会触发popstate事件,该事件中的状态对象(state object)包含stateObj的一个拷贝。该页面看起来像foo.html,尽管页面内容可能在popstate事件中被修改。url
若是咱们再次点击后退按钮,URL将变回http://mozilla.org/foo.html 文档将触发另外一个popstate事件,此次的状态对象为null。回退一样不会改变文档内容。
pushState()有三个参数:一个状态对象、一个标题(如今会被忽略),一个可选的URL地址。下面来单独考察这三个参数的细节:
状态对象(state object) — 一个JavaScript对象,与用pushState()方法建立的新历史记录条目关联。不管什么时候用户导航到新建立的状态,popstate事件都会被触发,而且事件对象的state属性都包含历史记录条目的状态对象的拷贝。
任何可序列化的对象均可以被当作状态对象。由于FireFox浏览器会把状态对象保存到用户的硬盘,这样它们就能在用户重启浏览器以后被还原,咱们强行限制状态对象的大小为640k。若是你向pushState()方法传递了一个超过该限额的状态对象,该方法会抛出异常。若是你须要存储很大的数据,建议使用sessionStorage或localStorage。
标题(title) — FireFox浏览器目前会忽略该参数,虽然之后可能会用上。考虑到将来可能会对该方法进行修改,传一个空字符串会比较安全。或者,你也能够传入一个简短的标题,标明将要进入的状态。
地址(URL) — 新的历史记录条目的地址。浏览器不会在调用pushState()方法后加载该地址,但以后,可能会试图加载,例如用户重启浏览器。新的URL不必定是绝对路径;若是是相对路径,它将以当前URL为基准;传入的URL与当前URL应该是同源的,不然,pushState()会抛出异常。该参数是可选的;不指定的话则为文档当前URL。
某种意义上,调用pushState()有点相似于设置window.location='#foo',它们都会在当前文档内建立和激活新的历史记录条目。但pushState()有本身的优点:
新的URL能够是任意的同源URL,与此相反,使用window.location方法时,只有仅修改 hash 才能保证停留在相同的document中。
根据我的须要来决定是否修改URL。相反,设置window.location='#foo',只有在当前hash值不是foo时才建立一条新历史记录。
你能够在新的历史记录条目中添加抽象数据。若是使用基于hash的方法,你只能把相关数据转码成一个很短的字符串。
注意pushState()方法永远不会触发hashchange事件,即使新的地址只变动了hash。
每当激活的历史记录发生变化时,都会触发popstate事件。若是被激活的历史记录条目是由pushState所建立,或是被replaceState方法影响到的,popstate事件的状态属性将包含历史记录的状态对象的一个拷贝。
history.replaceState()操做相似于history.pushState(),不一样之处在于replaceState()方法会修改当前历史记录条目而并不是建立新的条目。
当你为了响应用户的某些操做,而要更新当前历史记录条目的状态对象或URL时,使用replaceState()方法会特别合适。
1.利用popstate事件,监听点击返回事件。
2.触发事件时,判断当前页面的历史记录 是否有页面能够返回。
3.若是没有页面能够返回,则插入两条记录:
一、指定的跳转页面。
二、空记录。(使当前页面不发生变化)
//返回以前没页面则返回首页 function pushHistory() { if (history.length < 2) { var state = { title: "index", url: getHttpPrefix + "index.html" }; window.history.pushState(state, "index", location.href); state = { title: "index", url: "" }; window.history.pushState(state, "index", ""); } //lll("history.state" + history.state) //console.log(history.state) }
判断当前history中的记录个数,因为页面加载的时候,浏览器会自动push进一个记录。因此要判断长度是否小于2.
第三个参数是会替换当前地址栏的连接的,可是页面不会发生跳转。(我以前犯了个错误,将第三个参数设置为首页连接,致使了地址栏更改成首页连接,以致于在当前页的连接 都以首页为基础进行跳转,致使页面的全部连接都跳转错误了。)
setTimeout(function () { pushHistory() window.addEventListener("popstate", function (e) { lll("popstate"+window.history.state) if (window.history.state != null && window.history.state.url != "") { location.href = window.history.state.url } }); }, 300);