需求背景
在支付完成页面后,如果用户点击返回按钮,会返回到继续支付的页面。既然已经完成支付了,那么在用户点击返回按钮之后,就可以关闭页面了,这才是合理的做法。所以我们的目的就是,监听用户的页面返回事件,然后关闭页面。
监听返回事件
js里面有一个popstate事件,当页面返回时会触发这样一个事件。微信支付宝里,直接的监听该事件,在返回按钮点击时,并不能真正的触发popstate事件。需要通过pushstate先压入一个历史记录(通常是本页),例如:
$(function(){
pushHistory();
});
function pushHistory(){
var state = {
title: "",
url: "#"
};
window.history.pushState(state, "", "#");
}
这样在微信支付宝页面里,点击返回按钮就会触发popstate事件了,我们就可以进行相应的处理,例如:
window.addEventListener('popstate',function(){
alert('返回按钮点击');
});
由于有的浏览器,在页面刚进入的时候就会触发popstate事件,因此需要做一下兼容处理:
function listenPopstate(){
var initReady = false;
setTimeout(function(){
initReady = true;
},500); // 延迟500毫秒才真正处理popstate事件
window.addEventListener('popstate',function(){
if(initReady){
closeCurrentWindow();
}
});
}
关闭页面
微信和支付宝关闭页面是通过自己的jssdk处理的,例如:
WeixinJSBridge.call('closeWindow');//微信
AlipayJSBridge.call('closeWebview'); //支付宝
做过混合开发的应该对js调用原生api不陌生,这里就是通过js调用app的原生api关闭页面。
所以我们只需要判断浏览器是微信的还是支付宝的,再调用相应的关闭窗口的api就好了。
function closeCurrentWindow(){
var ua = navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i)=="micromessenger") {
WeixinJSBridge.call('closeWindow');//微信
} else if(ua.indexOf("alipay")!=-1){
AlipayJSBridge.call('closeWebview'); //支付宝
}else { // 普通浏览器
window.opener=null; // 因为安全策略,不允许js关闭非js打开的窗口,这里模拟js再打开一个,然后将其关闭
window.open('','_self');
window.close();
}
}
完整代码
$(function(){
pushHistory();
listenPopstate();
})
/**
* 监听popstate事件
*/
function listenPopstate(){
var initReady = false;
setTimeout(function(){
initReady = true;
},500);
window.addEventListener('popstate',function(){
if(initReady){
closeCurrentWindow();
}
});
}
/**
* 塞一个当前页的history实体
*/
function pushHistory(){
var state = {
title: "",
url: "#"
};
window.history.pushState(state, "", "#");
}
/**
* 关闭当前窗口
*/
function closeCurrentWindow(){
var ua = navigator.userAgent.toLowerCase();
if(ua.indexOf("micromessenger") !== -1) {
WeixinJSBridge.call('closeWindow');//微信
} else if(ua.indexOf("alipay")!=-1){
AlipayJSBridge.call('closeWebview'); //支付宝
}else { // 普通浏览器
window.opener=null; // 因为安全策略,不允许js关闭非js打开的窗口,这里模拟js再打开一个,然后将其关闭
window.open('','_self');
window.close();
}
}
后记
现在支付宝推出了jssdk代替jsapi,因此支付宝关闭浏览器可以用如下方式:
1-引入支付宝jssdk
<script src="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.inc.min.js"></script>
2-关闭浏览器
function exitCurrentWindow(){
var ua = navigator.userAgent.toLowerCase();
if(ua.indexOf("micromessenger") !== -1) {
weixinJSBridgeReady(function () {
WeixinJSBridge.call('closeWindow');//微信
});
} else if(ua.indexOf("alipay") !== -1){
ap.popWindow(); //支付宝使用了alipay jssdk(支付宝推荐替换jsapi),需要额外引入js文件。
} else { // 普通浏览器
window.opener=null; // 因为安全策略,不允许js关闭非js打开的窗口,这里模拟js再打开一个,然后将其关闭
window.open('','_self');
window.close();
}
}