功能需求描述

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