需求場景
有一天,頭兒給我提了這樣一個需求:
無論頁面如何跳轉,在首頁的時候再按返回,直接退出...
解決思路
關閉網頁好說,由於我們的專案是微信公眾號,直接呼叫微信瀏覽器的內建函式:
WeixinJSBridge.call('closeWindow')
複製程式碼
但是怎麼監聽到這個返回的事件呢?辦法呢還是有滴!
1. popstate-一個可以監聽歷史記錄點的API
JavaScript中沒有監聽物理返回鍵的API,所以通過監聽瀏覽器歷史記錄的變化來實現。
在HTML5就提供給我們 popstate 用來監聽歷史記錄點。
window.addEventListener("popstate", function(e) {
// 如果監聽到返回,就跳轉到百度首頁
window.location = 'http://www.baidu.com';
}, false);
複製程式碼
2. 監聽不到?pushState來告訴你為什麼
當我們完成兩個頁面來測試步驟一中程式碼的時候,發現返回的時候根本沒跳轉到百度首頁。
轉念一想不對啊,監聽到popstate事件的一瞬間就返灰到上一頁面了啊。為啥沒反應,心裡有點了逼數了啊!
不賣關子了,為了能返回後不回到上一級頁面,可以使用 pushState 來向歷史記錄棧中在插入一條新紀錄。
注意: 此處為了返回不跳轉,插入一個錨連結(此處有坑,下文解釋)就行
/**
* window.history.pushState(state, title, url)
*
* state:與要跳轉到的URL對應的狀態資訊。
* title:現在大多數瀏覽器不支援或者忽略這個引數,最好用null代替。
* url:要跳轉到的URL地址,不能跨域。
**/
var state = {
title: "title",
url: "#"
};
window.history.pushState(state, null, "#");
複製程式碼
沒意外的話,現在配合步驟一中程式碼,是可以監聽到頁面返回事件,從而跳轉到百度首頁。這也是網上能看到的絕大多數的思路。提醒一下,replaceState 雖然也可以改變歷史記錄棧,但是為了不破壞原有歷史記錄,此處最好使用 pushState。
3. 簡單整理一下前兩步中程式碼
// 封裝一下push歷史記錄的方法
function pushHistory() {
var state = {
title: "title",
url: "#"
};
window.history.pushState(state, null, "#");
}
// 在需要監聽的頁面執行該方法
pushHistory();
window.addEventListener("popstate", function(e) {
// 如果監聽到返回,就跳轉到百度首頁
window.location = 'http://www.baidu.com';
}, false);
複製程式碼
問題蒐集(網上搜集)
在微信中進入頁面就觸發了popstate事件
解決方法:定義boolean 變數bool=false。在頁面載入後,採用setTimeout方法設定1.5s的超時,在超時執行方法中設定bool=true。
// 封裝一下push歷史記錄的方法
function pushHistory() {
var state = {
title: "title",
url: "#"
};
window.history.pushState(state, null, "#");
}
// 在需要監聽的頁面執行該方法
var bool=false;
setTimeout(function(){
bool=true;
},1500);
pushHistory();
window.addEventListener("popstate", function(e) {
// 如果監聽到返回,就跳轉到百度首頁
if(bool){
window.location = 'http://www.baidu.com';
}
pushHistory();
}, false);
複製程式碼
這是網上看到好多人遇到的問題,雖然加了延遲,但是仍然解決不了我的問題,也許是應用場景的不同,此處暫時記下,做個參考
IOS微信端popstate自動觸發的解決
在IOS端的微信,如果頁面A->頁面B,如果兩個頁面都設定了返回重定向(也就是以上程式碼),按下返回鍵的時候,頁面A的popstate也會自動觸發,管你設定多少延遲也沒用。
當時在網上找了很多方法,都沒解決。
也許是自己手欠的緣故,有一次在毫無思路的情況下,在錨連結後加了個標識:
// 封裝一下push歷史記錄的方法
function pushHistory() {
var state = {
title: "title",
url: "#forward"
};
window.history.pushState(state, null, "#forward");
}
// 在需要監聽的頁面執行該方法
pushHistory();
window.addEventListener("popstate", function(e) {
// 如果監聽到返回,就跳轉到百度首頁
window.location = 'http://www.baidu.com';
}, false);
複製程式碼
你妹的,居然解決了
當然,此時我原來加的延遲也去掉了,反正對我來說也沒什麼用了!
總結: 在使用以上方式實現返回重定向的時候,切記不要只push進去一個空錨點。希望我這次的經驗能給遇到同樣問題的朋友一些經驗。如果有朋友有更好的解決辦法,也希望可以分享給我!