专栏首页Cocos Creator开发Web 游戏监听浏览器返回点击事件 !

Web 游戏监听浏览器返回点击事件 !

引用场景

做 web 游戏时,通常游戏是嵌入到 app 内部,通过 app 内部入口,跳转进入所开发的 web 游戏,app 内会预留返回功能,web 游戏可以使用 webview 自带的返回,实现游戏内不同场景的跳转。

比如游戏内有 a、b、c 三个场景,其中 a 场景是启动页面,a 场景进入 b 场景,b 场景进入 c 场景,从 c 场景中点返回,回到 b 场景,从 b 场景中点击返回,回到 a 场景, 从 a 场景中点击返回,调用 webview自身的返回事件。最后的效果如下图:

事件监听

当浏览器活动历时记录条目更改时,将触发 popstate 事件,如用户点击浏览器的回退按钮,或者在 javascript 代码中调用 history.back() 或者 history.forward() 方法,所以只需要在需要监听事件的场景

window.addEventListener('popstate', 
  e => {
      //添加点击返回处理逻辑
  },
  false
);

事件的消费和添加

仅仅监听事件,还是不够的,虽然写了监听逻辑,但是浏览器本身的返回事件还是触发的,这时候点击返回,还是会继续回到之前页面,所以需要添加一个新的状态,让浏览器不跳转到前一个页面,就需要用到 history.pushState() 方法。

history.pushState() 方法,是向当前浏览器会话的历史堆栈中添加一个状态 (state) ,添加以后,点击浏览器的返回,会消耗掉会话历史堆栈中栈顶的状态,也就是我们注册的最新的状态。

let state = { 
    title: "title", 
    url: null
}; 
window.history.pushState(state, "title", null);

其中 title 是标题,目前浏览器基本上是忽略这个参数,可以不管,url 是跳转地址,游戏内不需要跳转其他地址,直接传 null 即可。

事件的全局控制

使用 cocos creator 开发游戏,注册 popstate 监听事件后,在浏览器点击返回时,会在每个注册的位置触发,实际游戏场景中,只需要执行一次就够。

比如有 3 个游戏场景 a、b、c,从 a 中点击进入 b,从 b 中点击进入 c,b 和 c 内都注册了事件,这时候如果 b 和 c 分别直接注册,都会触发,导致界面显示出错。

像上述场景,就需要整体控制事件的添加和注册,每次添加事件和注册回调,放置到一个堆栈顶部,当事件触发时,从栈顶取出最新的一个,进行回调就行。

export default class PopStateMgr{
    /**
     * @desc: 注册返回事件
     * @param {type} 
     * @return: 
     */
    static push(onBackClick:any){
        PopStateMgr._events.push(onBackClick);
        let state = { 
            title: "title", 
            url: null
        }; 
        window.history.pushState(state, "title", null);
        window.addEventListener('popstate', 
            e => {
                PopStateMgr._onBackClick();
            },
            false
        );
    }

    private static _onBackClick(){
        if(PopStateMgr._events.length <= 0){
            return;
        }

        let func = PopStateMgr._events.pop();
        if(func != null){
            func();
        }
    }

    private static _events:any[] = [];
}

类似上面这种,在需要监听返回事件的场景脚本组件内,调用 push 及触发的回调事件就行。如本实例中,就在 b 场景开始时,调用 push 注册事件。

本文分享自微信公众号 - 一枚小工(caizj_cn),作者:一枚小工

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 微信经典飞机大战,承载多少人的回忆!

    游戏中主要由子弹 (bullet)、子弹管理 (bulletGroup)、敌人 (enemy)、敌人管理(enemyGroup)、英雄 (hero)、道...

    一枚小工
  • 从面试官角度观察到的程序员技能瓶颈,同时给出突破瓶颈的建议!

    原文链接:https://www.cnblogs.com/JavaArchitect/p/11616851.html

    一枚小工
  • Cocos Creator 如何制作拼图游戏,支持无规则形状!

    假设一张图,按照 row 行 col 列分成 count(=row * col) 份,由 count 份碎片组成,每个碎片有自己特定的形状,把所有碎片都拼接在...

    一枚小工
  • JSON与XML优缺点对比分析

    1. 定义介绍 1.1 XML定义 扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的...

    貟王軍
  • JSON与XML的区别比较

    1.定义介绍 (1).XML定义 扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,...

    mukekeheart
  • AI的数据、算法、算力“轮流坐庄”,NLP到了“数据为王”的时代

    工作人员齐整坐好,每个人都对着电脑全神贯注,一件又一件的“东西”在眼前划过,经过标准化处理就转到下一流程……这实际上是人工智能行业里的数据标注办公区一角。

    用户2908108
  • 社区leaf学习笔记|02. leaf服务器文件配置IP及端口

    可能大家下载的目录和截图不同,原因是本地leaf框架主编做了很多改动,增加了部分功能等,后面会上传到github。

    李海彬
  • ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于Wi-Fi模块(ESP8266)AT指令TCP透传方式,MQTT通信控制升级(加入数据校验)

      这样在不清楚BootLoader程序的情况下,就把第一份用户程序烧录进了相应的位置

    杨奉武
  • 马斯克:特斯拉要为自动雨刮器推出全新神经网络“Deep Rain”

    最近,特斯拉CEO马斯克在推特上宣布,他们推出了一个全新的神经网络“Deep Rain”,目的是改善自动雨刮器系统。

    镁客网
  • Digi-Capital:2017年AR/VR投资已达25亿美元,Q4已达10亿美元

    VRPinea

扫码关注云+社区

领取腾讯云代金券