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

栏目: 服务器 · 发布时间: 6年前

内容简介:1、利用2、利用

前言

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}
​复制代码

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

如上图,假设当前页面是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();
    }) 
}
​复制代码

三、优化**

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

还是这个图片

假设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'); 
    // 如果有问题,加个setTimeout
    window.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页面
    // TODO
    this.props.history.go(-2);
}
// 离开页面的时候取消监听hashchange
componentWillUnmount: function() {
    window.removeEventListener('hashchange',(state) => {
        this.back();
    }) 
}复制代码

兼容性可查看

有问题欢迎指正。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Trading and Exchanges

Trading and Exchanges

Larry Harris / Oxford University Press, USA / 2002-10-24 / USD 95.00

This book is about trading, the people who trade securities and contracts, the marketplaces where they trade, and the rules that govern it. Readers will learn about investors, brokers, dealers, arbit......一起来看看 《Trading and Exchanges》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

html转js在线工具
html转js在线工具

html转js在线工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换