功能需求描述
在工作开发过程中,遇见一个功能需求,要求在页面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);
}
}
})