有時候,因爲業務需求,須要監聽用戶的後退行爲,好比禁止用戶後退,好比想在用戶後退是給連接加上參數,這該怎麼辦呢?window對象的popstate事件就派上用場了html
每當處於激活狀態的歷史記錄條目發生變化時,popstate
事件就會在對應window
對象上觸發. 若是當前處於激活狀態的歷史記錄條目是由
history.pushState()
方法建立,或者由history.replaceState()方法修改過
的, 則popstate事件對象的
state
屬性包含了這個歷史記錄條目的state對象的一個拷貝.html5
可是,調用history.pushState()
或者history.replaceState()
不會觸發popstate事件. popstate
事件只會在瀏覽器某些行爲下觸發, 好比點擊後退、前進按鈕(或者在JavaScript中調用history.back()、history.forward()、history.go()
方法).ajax
要觸發popstate事件,須要兩步api
1.添加並激活一個歷史記錄條目(history.pushState)
瀏覽器
2.改變歷史記錄條目(用戶行爲,好比後退,前進)微信
如下是一個場景,當用戶觸發popstate事件時,檢測上一個頁面的url,若是是指定url,則加上指定的查詢字符串參數,便於後臺知道訪問url源自用戶的"後退"等動做,而不是直接輸入網址url
//添加並激活一個歷史條目 function pushHistory() { var state = { }; window.history.pushState(state, ""); } var url=document.referrer.replace('http://'+window.location.host,'');//上一頁的url if(url.indexOf('/mobile/index/index')>-1){//若是上一頁url是指定url var newIndex //用戶觸發popstate時間後,將要跳轉的url if(url.indexOf('?')>0){//已經攜帶了查詢字符串,則追加字符串 newIndex=document.referrer+'&popstate=1' }else{//沒有,則加上字符串參數 newIndex=document.referrer+'?popstate=1' } pushHistory();//添加並激活一個歷史條目
//當觸發popstate事件時,執行的邏輯
window.addEventListener("popstate", function(e) { window.location.href=newIndex;//根據本身的需求實現本身的功能,我這裏是跳轉,也能夠變成刷新,或者什麼都不作,若是是什麼都不作,須要再次添加並激活一個歷史記錄條目 }, false);
Tips:spa
1.後退/前進時,一般狀況下,瀏覽器會從新渲染頁面,但並無對當前頁面從新發起請求,並且控件的值不會變.code
2.微信瀏覽器(真機)的行爲有些不同,當後退時,若是後退後的一頁有popstate事件,則會當即觸發,這不是咱們想要的.所以須要作一個小的改動htm
var canPopstate=false //1秒內不運行執行popstate裏的邏輯 setTimeout(function () {//1秒後才真正執行popstate觸發後的邏輯 canPopstate=true },5000) window.addEventListener("popstate", function(e) { if(canPopstate){//能夠執行了 //業務邏輯 window.location.href='/' }else{//若是還沒到1秒用戶點擊了後退,則繼續添加歷史記錄 history.pushState({},'','aa=bb') } }, false); history.pushState({},'','acc=ddd')
以上代碼能夠防止微信瀏覽器內點擊後退時當即執行popstate裏的邏輯
3.不管當前頁面增長了幾個歷史,一旦請求其餘頁面,則後退只保留最新的歷史.