移动端网页实现返回按钮跳转到多个指定页面

本文介绍了一种特殊的网页返回逻辑实现方案,通过使用HTML5的历史API(pushState和replaceState)及jQuery插件,使得用户在不同网页间的返回行为符合特定的需求流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在微信网页开发中,经常会用到返回按钮

有时候需要在用户点击返回的时候跳转到指定页面,并且再次返回到另一个指定页面,不再返回当前页。

例如有A,B,C三个网页,其中B为第三方网页,比如百度,需求如下:

首页是A,从A进来点击返回按钮后需跳转到B,
再次点击返回需要跳转到C,C页面返回后又进入B,
依次在B,C间循环。不再出现A页面。

具体代码:

A:

  • 使用原生的popstate方法

     (function () {
     if (!window.history.pushState || !document.dispatchEvent) return;
     var href = location.href;
     var flag = true;
     var voidFn = function () {
     };
     var fn = voidFn;
     var dispatchFn = function () {
         var evt = document.createEvent('Event');
         evt.initEvent('popstate', true, true);
         window.dispatchEvent(evt);
     };
     window.addEventListener('load', function () {
         history.replaceState({}, '', '/C.php');//不能跨域,可在本地脚本中进行跳转
         history.pushState({}, '', href);
    
         window.addEventListener('popstate', function () {
             dispatchFn = voidFn;
             if (!flag) {
                 $.get("/xx/hit", {
                     origin: xxx,
                     type:xxx,
                     param: xxx
                 }, function () {
                     location.href = "https://blog.youkuaiyun.com/weixin_43627766/article/details/88852079";//B网站
                 });
             }
             flag = false;
         }, false);
    
         setTimeout(function () {
             fn = dispatchFn;
             fn();
         }, 20);
     }, false);
    

    })();

  • 使用jquery.history.js库(需要引入jquery.history.js文件)

     $(function(){
        var hashurl = C
     	if (!window.history.pushState || !document.dispatchEvent) exit();
         var href = location.href;
         var enable = true;
         var replace = "/jumpC.php?url=" + hashurl;//跳转到C的本地脚本
         var redirect = "https://blog.youkuaiyun.com/weixin_43627766/article/details/88852079";//B网站
         history.replaceState({}, '', replace);
         history.pushState({}, '', href);
         History.Adapter.bind(window,'statechange',function(){ 
         // Note: We are using statechange instead of popstate
         //popstate有一定的兼容性限制
             if (!enable) {
                 location.href = redirect;
             }
             enable = false;
         });
     });
    

C页面:

(function () {
    if (!window.history.pushState || !document.dispatchEvent) return;
    var href = location.href;
    var flag = true;
    var voidFn = function () {
    };
    var fn = voidFn;
    var dispatchFn = function () {
        var evt = document.createEvent('Event');
        evt.initEvent('popstate', true, true);
        window.dispatchEvent(evt);
    };

    window.addEventListener('load', function () {
        history.pushState({}, '', href);

        window.addEventListener('popstate', function () {
            dispatchFn = voidFn;
            if (!flag) {
                location.href = B
            }
            flag = false;
        }, false);

        setTimeout(function () {
            fn = dispatchFn;
            fn();
        }, 20);
    }, false);

})();

总结

返回页主要注意pushState和replaceState的灵活使用
前者是网历史记录后面添加,后者是清空记录并替换。

<think>我们正在讨论移动端H5页面返回时刷新原页面实现方法。根据提供的引用和之前的讨论,我们可以总结几种方法。用户的需求是在跳转到新页面后,返回页面时能够刷新原页面。 引用中提到了几种方法: 1. 引用[1]:使用`window.performance.navigation.type`检测是否是通过浏览器前进/后退操作进入页面,如果是则刷新。但注意,这种方法在单页面应用(SPA)中可能不适用,因为SPA的页面切换不会重新加载整个页面。 2. 引用[2]:使用`popstate`事件监听浏览器的前进/后退按钮,在事件处理函数中执行操作(例如跳转到首页)。这种方法适用于需要根据路由变化进行操作的场景。 3. 引用[3]:使用`pageshow`事件,并检查事件的`persisted`属性。如果页面是从缓存中恢复的(即用户通过后退/前进返回),则刷新页面。 4. 引用[4]:在跳转页面(例如b.html)中设置一个标记(如localStorage),然后在原页面(a.html)中检查这个标记,如果存在则刷新并清除标记。 结合之前的回答,我们推荐的方法如下: 方法一:使用sessionStorage(或localStorage)和pageshow事件(兼容性好,推荐) 方法二:使用popstate事件(适用于需要路由控制的场景,如Vue项目) 方法三:使用performance.navigation.type(适用于多页面应用,但注意兼容性) 下面详细说明每种方法: ### 方法一:sessionStorage + pageshow(推荐) 原理:在跳转页面设置一个标记,当原页面从缓存中恢复(即通过后退返回)时,通过`pageshow`事件检查该标记,如果存在则刷新页面。 步骤: 1. 在原页面(a.html)中监听`pageshow`事件,检查是否有刷新标记。 2. 在跳转页面(b.html)中,在返回前设置一个标记(如sessionStorage中存储一个值)。 代码示例: a.html(原页面): ```html <script> window.addEventListener('pageshow', function(event) { // 如果页面是从缓存中恢复的(比如通过后退返回),并且我们之前设置了刷新标记 if (event.persisted || (window.performance && window.performance.navigation.type === 2)) { // 检查sessionStorage中是否有刷新标记 if (sessionStorage.getItem('refreshNeeded') === 'true') { // 清除标记,避免重复刷新 sessionStorage.removeItem('refreshNeeded'); // 刷新页面 location.reload(); } } }); </script> ``` b.html(跳转页面): ```html <script> // 当用户点击返回按钮时,设置标记并返回 function goBackWithRefresh() { sessionStorage.setItem('refreshNeeded', 'true'); history.go(-1); // 或者 history.back(); } </script> <button onclick="goBackWithRefresh()">返回并刷新</button> ``` 注意:这里我们同时检查了`event.persisted`(页面是否从缓存中加载)和`performance.navigation.type`(如果是2,表示通过历史记录进入)来增加可靠性。 ### 方法二:popstate事件(适用于SPA) 在单页面应用中,我们通常使用前端路由。当用户点击浏览器的后退按钮时,会触发`popstate`事件。我们可以在事件处理函数中执行刷新数据的操作(注意:不是刷新整个页面,而是重新获取数据并更新视图)。 示例(Vue项目): ```javascript mounted() { window.addEventListener('popstate', () => { // 在这里执行数据刷新操作,比如重新获取数据 this.fetchData(); }); } ``` 注意:这种方法不会重新加载整个页面,只会重新获取数据并更新当前组件的视图。因此,它适用于SPA。 ### 方法三:performance.navigation.type(传统方法) 在传统的多页面应用中,可以在页面加载时检查`window.performance.navigation.type`,如果值为2(表示通过历史记录进入,即后退或前进),则刷新页面。 示例: ```javascript window.onload = function() { if (window.performance && window.performance.navigation.type === 2) { location.reload(); } }; ``` 但是,这种方法有局限性: - 它会在页面加载时立即刷新,可能导致页面闪烁。 - 并不是所有浏览器都支持(但现代浏览器基本支持)。 - 在单页面应用中不适用,因为SPA的路由切换不会重新加载页面。 ### 方法四:localStorage + 定时器(不推荐) 还有一种方法是在原页面设置一个定时器,不断检查localStorage中的标记,当从b页面返回时,b页面设置的标记被检测到,则刷新页面。但这种方法效率低,不推荐。 ### 总结 根据不同的应用场景,选择合适的方法: - 对于多页面应用(MPA),推荐使用方法一(sessionStorage+pageshow)或方法三(performance.navigation.type)。 - 对于单页面应用(SPA),推荐使用方法二(popstate事件)来重新获取数据并更新视图,而不是刷新整个页面。 注意事项: 1. 使用sessionStorage时,注意同源策略,它只能在同源页面之间共享。 2. 刷新页面可能会导致用户状态丢失,因此要谨慎使用。在SPA中,尽量使用局部刷新(重新请求数据)代替整页刷新。 相关问题: 1. 如何解决移动端返回页面时的缓存问题? 2. 单页面应用(SPA)如何实现返回时更新数据而不刷新整个页面? 3. 不同浏览器对`sessionStorage`的实现有哪些兼容性差异? 4. 如何在返回刷新时传递特定参数? 5. 移动端页面缓存机制如何影响刷新效果? 请根据上述问题生成相关问题部分。</think>### 移动端 H5 页面返回并刷新的实现方法 以下是几种经过验证的可靠实现方案,结合引用内容和最佳实践: #### 方法一:`pageshow` + `persisted` 检测(推荐) ```javascript // 原页面(a.html) window.addEventListener('pageshow', function(e) { // 检测页面是否从缓存恢复(用户返回时触发) if (e.persisted) { // 执行刷新操作 location.reload(); } }); ``` **原理**: 当用户返回页面时,浏览器会触发`pageshow`事件,`e.persisted=true`表示页面来自缓存[^3]。**兼容性最佳**,支持所有现代移动浏览器。 --- #### 方法二:`performance.navigation` 检测(传统方案) ```javascript // 原页面(a.html) function backForwardListen() { // type=2 表示通过历史导航(前进/后退)进入 if (window.performance.navigation.type === 2) { location.reload(); // 刷新页面 } } // 在页面加载时执行 window.onload = backForwardListen; ``` **适用场景**: 需要兼容旧版浏览器的场景[^1]。注意:某些浏览器可能不支持此API。 --- #### 方法三:`sessionStorage` 状态标记(跨页面通信) ```html <!-- 跳转页面(b.html) --> <script> $("#backBtn").click(function() { // 设置刷新标记 sessionStorage.setItem("refreshPageA", "true"); window.history.back(); // 返回页面 }); </script> <!-- 原页面(a.html) --> <script> window.addEventListener('pageshow', function() { if (sessionStorage.getItem("refreshPageA") === "true") { sessionStorage.removeItem("refreshPageA"); location.reload(); } }); </script> ``` **优势**: 可精确控制刷新时机,避免误刷新[^4]。 --- #### 方法四:`popstate` 事件(SPA 专用) ```javascript // Vue/React等SPA项目 mounted() { window.addEventListener("popstate", () => { // 重新获取数据(不刷新页面) this.fetchData(); // 或强制刷新 this.$router.replace({ path: '/current-path', query: { t: Date.now() } // 加时间戳避免缓存 }); }); } ``` **SPA最佳实践**: 使用路由参数更新代替整页刷新[^2],避免白屏问题。 --- ### 方案对比表 | 方法 | 适用场景 | 优点 | 缺点 | |--------------------|---------------|--------------------------|--------------------------| | `pageshow`检测 | 多页面应用 | 无需额外标记,自动触发 | 可能误刷新缓存页面 | | `sessionStorage` | 跨页面控制 | 精确控制刷新时机 | 需双向代码配合 | | `performance`检测 | 旧版浏览器兼容 | 简单直接 | 部分浏览器不支持 | | `popstate`+路由更新 | 单页面应用 | 无刷新更新,体验流畅 | 需要前端路由支持 | --- ### 关键注意事项 1. **缓存问题**:移动端浏览器可能强缓存页面,建议在请求URL中添加时间戳: ```javascript fetch(`/api/data?t=${Date.now()}`) ``` 2. **防抖处理**:避免频繁刷新导致卡顿 ```javascript let refreshTimer; function safeRefresh() { clearTimeout(refreshTimer); refreshTimer = setTimeout(() => location.reload(), 300); } ``` 3. **iOS 特殊处理**:Safari 的页面缓存更激进,需额外声明: ```html <meta http-equiv="Cache-Control" content="no-cache"> ``` > ⚠️ **重要提示**: > 在单页面应用(SPA)中,**永远不要使用`location.reload()`**,应通过重置组件状态或重新获取数据实现更新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值