JS监听手机物理返回键(及IOS微信端的bug)

需求场景

有一天,头儿给我提了这样一个需求:跨域

不管页面如何跳转,在首页的时候再按返回,直接退出...浏览器

解决思路

关闭网页好说,因为咱们的项目是微信公众号,直接调用微信浏览器的内置函数:bash

WeixinJSBridge.call('closeWindow')
复制代码

可是怎么监听到这个返回的事件呢?办法呢仍是有滴!微信

1. popstate-一个能够监听历史记录点的API

JavaScript中没有监听物理返回键的API,因此经过监听浏览器历史记录的变化来实现。函数

在HTML5就提供给咱们 popstate 用来监听历史记录点。测试

window.addEventListener("popstate", function(e) { 
    // 若是监听到返回,就跳转到百度首页
    window.location = 'http://www.baidu.com';
}, false); 
复制代码

2. 监听不到?pushState来告诉你为何

当咱们完成两个页面来测试步骤一中代码的时候,发现返回的时候根本没跳转到百度首页。 ui

hi

转念一想不对啊,监听到popstate事件的一瞬间就返灰到上一页面了啊。为啥没反应,内心有点了逼数了啊!url

不卖关子了,为了能返回后不回到上一级页面,可使用 pushState 来向历史记录栈中在插入一条新纪录。spa

注意: 此处为了返回不跳转,插入一个锚连接(此处有坑,下文解释)就行code

/**
* 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进去一个空锚点。但愿我此次的经验能给遇到一样问题的朋友一些经验。若是有朋友有更好的解决办法,也但愿能够分享给我!

相关文章
相关标签/搜索