功能需求描述
在工作開發過程中,遇見一個功能需求,要求在頁面A.html對Android手機的物理返回按鍵進行監聽,當用戶點擊物理返回按鍵時,彈出confirm彈框:用戶點擊“確定”,跳轉至頁面B;用戶點擊取消,仍停留在當前頁面,此時點擊物理返回按鍵,依舊彈出confirm彈框,重複上述過程。
實現邏輯
當前,js並沒有對應Android手機物理返回按鍵這一事件的API,無法直接對這一事件進行監聽以及後續操作,因此,我們只能通過js的其他方法,來實現近似的效果。這裏,我們考慮的是使用history有關的方法來實現。接下來,簡要介紹一下本次需要使用的幾個方法
window.history.pushState(state, title, utl) :在頁面中直接創建一個history實體,並將其添加到歷史記錄中;
state:對象,可存儲數據,可以通過 history.state方法進行讀取;
title:對應歷史記錄的標題
url:創建的歷史記錄的鏈接。進行歷史記錄操作時會跳轉到該鏈接。
popstate:history實體被改變時,觸發該事件;
具體實現的思路就是,在頁面加載時,通過window.history.pushState 方法,創建一個無實際使用意義的history實體。隨後,通過addEventLister方法對popstate方法進行進行,並綁定自己想要執行的函數。需要注意的是,這裏的addEventListener的 use Capture 參數需要爲默認的false,使其在冒泡階段執行。
在上面創建新的無意義history實體的用處是,由於用戶點擊Android物理返回按鍵時,會在觸發popstate事件時,銷燬最新的history實體,通過創建新的無意義history實體則可以防止有用的history實體被誤銷燬,導致其他bug出現。
同理,由於每次返回都會消耗一個 history 實體,若用戶選擇取消離開,則需要繼續 pushState 一個新的實體,確保停留在當前頁面。不然的話,則會出現第二次點擊物理返回按鍵時,不執行希望的函數,而直接回退的問題,即沒有實現第二次及以後的物理返回按鍵監聽。
實現代碼
$(function(){
addEventBack();
function addEventBack(){
pushHistory();
window.addEventListener("popstate",addBackKey, false);
function pushHistory() {
var state = {
title: "title",
url: "#"
};
window.history.pushState(state, "title", "#jjjj");
}
}
function addBackKey(){
var res = confirm("是否確認離開當前頁面?");
if (res == true) {
window.location.href="/aaa.html";
}else{
addEventBack();
history.pushState(state, null, location.href);
}
}
})