JS监听页面回退前进的方案

您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~

前言

在业务中遇到需求,App中的H5页面跳转到其他外链页面,外链页面修改了整个APP中的导航栏样式,回退到当前页面,导航栏受到了影响,造成了用户体验下降的问题,步骤如下:

  1. 位于自身BUC下的H5页:
  1. 点击查看活动,跳转到外链活动页(由其他BU提供的H5),非可控,APP标题栏被隐藏处理:
  1. 回退页面,回到自身H5页,问题发生,标题栏由于被上一步隐藏处理了,影响到了本BU项目的视觉:

问题解决

问题解决的思路无非两种~

  1. 自己做监听,由于APP与浏览器不同,在回退页面不会触发页面的刷新,因此要监听页面的回退做APP标题栏重置操作;
  2. 找提供活动页的研发,在活动页销毁时重置标题栏;

我们选择第一种,因为第二种别人不干。

onpageshow

通过window.onpageshow可以监听到页面展示,我们在当前页做一个监听操作,与window.onload不同之处是,当页面主动刷新渲染后,每次加载页面,都会走到onpageshow的回调,这就很符合页面回退做处理的业务场景。

根据思路写出如下代码:

typescript 复制代码
const ShopChaimDetail = () => {
  // ***

  useEffect(() => {
    window.onpageshow = (event) => {
      console.log('页面加载了');
    };
    return () => {
      window.onpageshow = () => {};
    };
  }, []);
  
  // ***
};

那么如何判断页面此次加载是属于主动刷新,还是history前进回退呢?

performance.navigation.type

performance.navigation.type用于判断网页来源类型,一共有四种类型:

  1. 网页通过点击链接、地址栏输入、表单提交、脚本操作等方式加载,相当于常数performance.navigation.TYPE_NAVIGATE
  2. 网页通过"重新加载"按钮或者location.reload()方法加载,相当于常数performance.navigation.TYPE_RELOAD
  3. 网页通过"前进"或"后退"按钮加载,相当于常数performance.navigation.TYPE_BACK_FORWARD
  4. 任何其他来源的加载,相当于常数performance.navigation.TYPE_RESERVED

我们需要在页面回退时重置APP标题栏的样式,因此判断window.performance.navigation.type === 2即可。

改装一下上面的代码块:

typescript 复制代码
const ShopChaimDetail = () => {
  // ***

  useEffect(() => {
    getApplyDetail(true);
    window.onpageshow = (event) => {
      listenWebViewBack(event);
    };
    return () => {
      window.onpageshow = () => {};
    };
  }, []);

  /**
   * @description: 监听容器中回退页面的方式回到当前页,重置标题栏样式
   * @param {*} event
   * @return {*}
   */
  const listenWebViewBack = (event) => {
    if (
      event.persisted ||
      (window.performance && window.performance.navigation.type == 2)
    ) {
      //页面是从缓存中获取的数据||是通过浏览器后退来到该页面
      showNativeTabbar();
      if (isIos) {
        resetIosTabbar();
      } else {
        resetAndroidTabbar();
      }
    }
  };
  
  // ***
};

这样通过onpageshow监听 + performance.navigation.type判断网页来源就实现了监听回退的方案。

结尾

本文属于博主日常工作开发记录下来的有意思的方案,如果对你有帮助,那真是太好不过了~

如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~

相关推荐
不会写DN7 分钟前
Gin 日志体系详解
前端·javascript·gin
冬夜戏雪29 分钟前
实习面经记录(十)
java·前端·javascript
爱学习的程序媛2 小时前
【Web前端】JavaScript设计模式全解析
前端·javascript·设计模式·web
小码哥_常2 小时前
从SharedPreferences到DataStore:Android存储进化之路
前端
老黑2 小时前
开源工具 AIDA:给 AI 辅助开发加一个数据采集层,让 AI 从错误中自动学习(Glama 3A 认证)
前端·react.js·ai·nodejs·cursor·vibe coding·claude code
薛先生_0992 小时前
js学习语法第一天
开发语言·javascript·学习
jessecyj2 小时前
Spring boot整合quartz方法
java·前端·spring boot
苦瓜小生3 小时前
【前端】|【js手撕】经典高频面试题:手写实现function.call、apply、bind
java·前端·javascript
天若有情6733 小时前
前端HTML精讲03:页面性能优化+懒加载,搞定首屏加速
前端·性能优化·html
踩着两条虫3 小时前
AI驱动的Vue3应用开发平台深入探究(十):物料系统之内置组件库
android·前端·vue.js·人工智能·低代码·系统架构·rxjava