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判断网页来源就实现了监听回退的方案。

结尾

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

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

相关推荐
donecoding7 小时前
别再让 pnpm 跟着 nvm 跑了!独立安装终极指南
前端·node.js·前端工程化
不可能的是7 小时前
从 /simplify 指令深挖 Claude Code 多 Agent 协同机制
javascript
GISer_Jing7 小时前
AI全栈转型_TS后端学习路线
前端·人工智能·后端·学习
竹林8187 小时前
被The Graph的GraphQL查询坑了三天,我用一个真实DeFi项目把链上数据索引彻底搞懂了
前端·graphql
漫游的渔夫7 小时前
前端开发者做 Agent:别只会执行,用 4 类失败策略让 AI 知道怎么停
前端·人工智能·typescript
用户059540174467 小时前
把多级缓存一致性验证从手工测试换成 Pytest 参数化,Bug 排查时间缩短 90%
前端·css
暗不需求7 小时前
深入理解 LangChain:AI 应用开发框架的工程化实践
前端·langchain
用户059540174467 小时前
把 Redis 持久化测试从 800 行 Shell 换成 30 行 pytest,排错效率翻了 10 倍
前端·css
Rkgua8 小时前
事件流模型是什么和DOM事件模型等关系
javascript
GISer_Jing8 小时前
AI全栈工程师知识体系全景:从前后端核心架构到落地项目全拆解
前端·人工智能·后端·ai编程