前言

1.主要是返回是默认的浏览器返回事件是返回上一个页面。

2.处理页面各种弹窗,点击物理返回应该隐藏这些弹窗而不是直接返回页面。

3.总结下问题,h5应该希望能监听到返回事件并且做一些处理。

相关知识

1、利用popstate事件,点击浏览器前进,后退会触发popstate事件。

2、利用hashchange事件,页面hash改变是会触发此事件(适合react,vue单页面应用)。

一、window.onpopstate

每当处于激活状态的历史记录条目发生变化时,popstate事件就会在对应window对象上触发. 如果当前处于激活状态的历史记录条目是由history.pushState()方法创建,或者由history.replaceState()方法修改过的, 则popstate事件对象的state属性包含了这个历史记录条目的state对象的一个拷贝.

调用history.pushState()或者history.replaceState()不会触发popstate事件. popstate事件只会在浏览器某些行为下触发, 比如点击后退、前进按钮(或者在JavaScript中调用history.back()、history.forward()、history.go()方法).

history.pushState()不会刷新页面,往历史记录中添加一条记录。

history.replaceState()不会刷新页面,替换当前页面记录,不会在历史记录中新增。

兼容性:当网页加载时,各浏览器对popstate事件是否触发有不同的表现,Chrome 和 Safari会触发popstate事件, 而Firefox不会.

可参考相关文档。

假如当前网页地址为example.com/example.htm…,则运行下述代码后:

window.onpopstate = () => {} 等同于 window.addEventListener('popstate',() => {});
​
window.onpopstate = function(event) {alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
};
//绑定事件处理函数.
history.pushState({page: 1}, "title 1", "?page=1");    //添加并激活一个历史记录条目 http://example.com/example.html?page=1,条目索引为1   当前记录有两条记录(包括最开始的)
history.pushState({page: 2}, "title 2", "?page=2");    //添加并激活一个历史记录条目 http://example.com/example.html?page=2,条目索引为2   当前记录有三条记录
history.replaceState({page: 3}, "title 3", "?page=3"); //修改当前激活的历史记录条目 http://ex..?page=2 变为 http://ex..?page=3,条目索引为3  当前记录有三条(replaceState会替换第三条条)
history.back(); // 弹出 "location: http://example.com/example.html?page=1, state: {"page":1}"
history.back(); // 弹出 "location: http://example.com/example.html, state: null
history.go(2);  // 弹出 "location: http://example.com/example.html?page=3, state: {"page":3}
​复制代码

如上图,假设当前页面是A页面,跳转到B页面,B页面打开dialong弹窗,这个时候点击返回,默认是返回到A页面。这种体验是很差的,优化体验,这个时候需要优化这种体验性能问题。

场景:在B页面中有个弹窗,点击返回,要关闭弹窗,再次点击,返回到A页面。

代码如下:

// 假设A页面为http://www.example.com/a.html
// B页面是http://www.example.com/b.html
// 下面以react生命周期为例
componentDidMount: function() {window.addEventListener('popstate',(state) => {// 监听到返回事件,注意,只有触发了返回才会执行这个方法console.log(state);this.back();})
}
// 假设点击打开对话窗,利用pushState添加一天记录
openDialong: function() {// 此时页面地址为b.html?page=1,但是页面没有刷新。并且不会触发popstate方法history.pushState({page: 1}, "title 1", "?page=1");// TODO}
// 弹窗已存在,并且点击了返回事件,此时页面b.html?page=1--->b.html,并触发popstate事件
back: function() {// 页面在用户看来是没有刷新的,此时是关闭dialong// TODO}
// 离开页面的时候取消监听popstate
componentWillUnmount: function() {window.removeEventListener('popstate',(state) => {this.back();})
}复制代码

二、window.onhashchange

当 一个窗口的 hash (URL 中 # 后面的部分)改变时就会触发 hashchange 事件(参见 location.hash)。

if ("onhashchange" in window) {alert("该浏览器支持 hashchange 事件!");
}
​
function locationHashChanged() {if (location.hash === "#somecoolfeature") {somecoolfeature();}
}
​
window.onhashchange = locationHashChanged;复制代码

还是以上面场景为例:

// 假设A页面为http://www.example.com/a.html#/a
// B页面是http://www.example.com/a.html#/b
// 下面以react生命周期为例
componentDidMount: function() {window.addEventListener('hashchange',(state) => {// hash改变就会触发const href = location.href;// 当前hash中不存在?page=1是触发(初始化刚进来是不会触发这个方法的)if (href.indexOf('?page=1') < 0) {this.back();}})
}
// 假设点击打开对话窗,利用pushState添加一天记录
openDialong: function() {// 此时页面地址为a.html?page=1,但是页面没有刷新。并且不会触发popstate方法// history.pushState({page: 1}, "title 1", "?page=1");// 不过此时会触发hashchange,但是加个判断;this.props.history.push('/b?page=1'); // TODO}
// 弹窗已存在,并且点击了返回事件,此时页面a.html?page=1--->a.html,并触发hashchange事件
back: function() {// 页面在用户看来是没有刷新的,此时是关闭dialong// TODO}
// 离开页面的时候取消监听hashchange
componentWillUnmount: function() {window.removeEventListener('hashchange',(state) => {this.back();})
}
​复制代码

三、优化**

还是这个图片

假设A是首页,B详情页面,C是支付页面,D是结果页面。(我们希望D不能返回到C页面)。

假设要从D页面跳转到B页面(B,C,D也一样), 从结果页面D中点击按钮跳转到详情B页面,可再次购买。

有以下方法:

方法一:location.href = 'http://www.example/b.html';
方法二:history.go(-2);复制代码

主要区别:

方法一会往历史记录中添加新的记录,变成A—>B—>C—>D—>B。

此时点击物理返回,就会回到D页面。而这不是我们要的结果。

方法二是回到历史记录中,不会新增记录,链路还是A—>B—>C—>D。

D页面不应该回到C页面

此时我们就可以用到上面的方法,点击返回利用history.go()的方法,回到我们想到的页面。

// D页面---->B页面
componentDidMount: function() {this.props.history.push('/b?page=1'); // 如果有问题,加个setTimeoutwindow.addEventListener('hashchange',(state) => {// hash改变就会触发const href = location.href;// 当前hash中不存在?page=1是触发(初始化刚进来是不会触发这个方法的)if (href.indexOf('?page=1') < 0) {this.back();}})
}
// 并且点击了返回事件,此时页面d.html?page=1--->d.html,并触发hashchange事件
back: function() {// 页面在用户看来是没有刷新的,此时是回到B页面// TODOthis.props.history.go(-2);
}
// 离开页面的时候取消监听hashchange
componentWillUnmount: function() {window.removeEventListener('hashchange',(state) => {this.back();})
}复制代码

兼容性可查看。

有问题欢迎指正。

移动端h5监听浏览器返回操作(目前在react项目中用到)相关推荐

  1. h5监听浏览器返回,关闭浏览器

    需求 监听浏览器返回,点击返回时,显示弹窗,弹窗中有两个按钮,a按钮:关闭当前浏览器,b按钮:关闭弹窗 mounted(){// 向历史记录中插入了当前页,//为了ios首次进入页面出现底部返回按钮i ...

  2. html5 浏览器退回事件,html5的pushstate以及监听浏览器返回事件的实现

    这篇文章主要介绍了html5的pushstate以及监听浏览器返回事件的实现,主要介绍了pushstate的使用,以及监听浏览器的解决等问题,感兴趣的可以一起来了解一下 pushstate与监听浏览器 ...

  3. 【不得不看的几种js监听浏览器返回,关闭,刷新】

    监听浏览器切换页面 //切换页面document.addEventListener('visibilitychange', function () { //浏览器切换事件if (document.vi ...

  4. js监听浏览器返回、后退、上一页按钮事件方法

    一.监听浏览器事件 ⼤家知道在页⾯中我们可以使⽤javascript window history,后退到前⾯页⾯,但是由于安全原因javascript不允许修改history ⾥已有的url链接,但 ...

  5. vue3实现H5监听浏览器回退并阻止回退

    当你的移动端页面有弹窗的组件并且这个组件不是来自于某些知名的组件库,你是否有这样的需求?当用户唤起弹窗之后又按下了手机自带的回退键,弹窗之前的页面也被关掉了,而用户本身的意愿是关掉弹窗而已.如果你也有 ...

  6. h5 监听浏览器被切换到后台或者手机锁屏再次唤起事件

    H5有一个事件叫 visibilitychange ,当浏览器的某个标签页切换到后台,或从后台切换到前台时就会触发该消息,代码如下: document.addEventListener("v ...

  7. 监听浏览器返回上一页

    页面1 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title ...

  8. 监听浏览器的返回事件,禁止浏览器返回

    //禁止页面后退 history.pushState(null,null,document.URL); window.addEventListener('popstate',function(){// ...

  9. iOS小技能:监听H5页面goBack返回事件 网页监听APP返回键 (NavigationBackItemInjection)

    文章目录 引言 I . iOS监听H5页面goBack返回事件 1.1 UIWebView 监听H5页面goBack返回事件 1.2 WKWebView监听H5页面goBack返回事件 II. 网页监 ...

最新文章

  1. 你的 Redis 为什么变慢了?
  2. TCP全局同步问题发生的原因
  3. CentOS6虚拟机下面配置双网卡
  4. Spring Boot 几条最佳实践!
  5. 搜索引擎CACHE策略研究
  6. 各类木材强度_凯狄解析各类抽芯铆钉的工作原理
  7. Java 开发者每天都在做什么?
  8. 信息学奥赛C++语言:求阶乘
  9. Exchange 2013 SP1部署系列7:发送连接器的配置
  10. xFire两种客户端的传递参数
  11. 如何保养与维护笔记本硬盘
  12. 人体姿态识别OpenPose
  13. 双光耦开关电源电路图_简单的开关电源电路图大全(六款简单的开关电源电路设计原理图详解)...
  14. 【协议森林】IPv6过渡技术之隧道和翻译技术
  15. matlab将声音和噪声叠加,如何用matlab产生一个多次叠加的含高斯噪声的正
  16. 【Flutter 问题系列第 49 篇】在 Flutter 中如何给组件设置背景色、圆角、边框、形状、阴影、渐变色、背景图片等效果
  17. 计算机全选的键盘,全选快捷键是什么,教您电脑全选快捷键是什么
  18. matlab图形与动画设计 pdf,MATLAB图形与动画设计
  19. Spring中的静态代理和动态代理
  20. java判断long相等_java判断long类型字符是否相等的方法

热门文章

  1. mysql的ps.setmaxrows_mysql自定义函数实现表的指定列进行数据脱敏(PS:来自mysql小白的提问)...
  2. Java 解析Excel(xls、xlsx两种格式)
  3. 人人开源之代码生成器(renren-generator)
  4. ipython的使用
  5. 排序算法的总结——Java实现
  6. 【BZOJ-1952】城市规划 [坑题] 仙人掌DP + 最大点权独立集(改)
  7. Browser增加下载路径选择功能
  8. Solr集群安装Version5.5.2(cloud模式)
  9. user-agent java_user-agent
  10. InputStreamReader笔记