H5嵌套到小程序、APP,还能埋点统计?看完这篇便知晓
发布于 3 年前 作者 ishen 3720 次浏览 来自 分享

赠人玫瑰,手有余香。先点赞,再查看哇。

业务需求

最近产品需要做一个埋点,无论是预览商品还是预览企业信息都需要统计改用户停留的时长,但是这个里有个特点,就是商品和企业信息都是用H5写的,最终这个H5页面会嵌套自家产品小程序和自己产品安卓端和IOS端,由于嵌套的原因,需要处理的东西确实会比较复杂,并且还是嵌套到三个不同的宿主环境里,想想都会头疼,这样会导致有些事件H5是无法监听到的。

碰到的难题

  • 上一篇文章,我有讲解在H5中,如何解决关闭浏览器发送统计信息及测试是否发送成功的问题;使用navigator.sendBeacon发送接口及window.addEventListener('unload', function(){}, false)来监听是否关闭浏览器,更多详情点我

  • 这里将要讲解的难点有2个:

    • 1.嵌套进去的H5页面,在APP或小程序中,用户把软件切换到后台我们都无法监听。
    • 2.用户在使用嵌套的小程序和IOS宿主环境中点击左上角自带返回按钮,H5都无法监听到用户退出了当前H5页面。

解决思路

  • 解决上面的难点之前,我想讲讲,统计时间预览怎么算,如果我不猜错,估计很多人都会和我一开始看见需求一样,什么统计预览时间?搞个定时器?这样会不会很消耗性能?我的代码会不会跑着跑着就蹦?一连串的疑问。

    • 其实统计时间并没有那么难,我们只需要记录一次即可,我们在进入H5页面时,我们就new一个时间戳(new Date).getTime()把它保存到全局,如何在要调接口统计时长时,我们在(new Date).getTime()弄一个时间戳减去进来时保存的时间戳即可得到一个__预览时间__,这里相减是毫秒,自己转化下即可。
  • 解决完时间统计问题,我们要来解决今天的难点问题。

    • 解决这两个难点问题,我们H5主要使用一个监听事件visibilitychange,这个时间可以监听页面是否隐藏,下面我们详细介绍:

visibilitychange

当其选项卡的内容变得可见或被隐藏时,会在文档上触发 visibilitychange (能见度更改)事件。

当 visibleStateState 属性的值转换为 hidden时,Safari不会按预期触发visibilitychange; 因此,在这种情况下,您还需要包含代码以侦听 pagehide 事件。

出于兼容性原因,请确保使用  document.addEventListener而不是window.addEventListener来注册回调。 Safari <14.0仅支持前者。

重要代码

document.addEventListener("visibilitychange", function() {
  if (document.visibilityState === 'visible') {
      // 页面被显示
    // backgroundMusic.play();
  } else {
      // 页面被隐藏
    // backgroundMusic.pause();
  }
});

逻辑思路

  • 全局设置一个变量用于记录初始时间,当页面隐藏(例如:切换后台)监听到visibilitychange下的document.visibilityState === 'hidden'时,我们就把时间统计发送到服务器;当document.visibilityState === 'visible'时,我们又开始新的统计时间,这样就可以精准把需要统计的时间完成到服务器。

  • 此时新的问题开始出现了,就是嵌套H5后,在ios系统中,直接点击系统右上角的返回按钮,是无法触发visibilitychange事件的,这就让我们很困惑了,有人会提出,那不是可以监听关闭浏览器或者关闭网站事件,不就可以解决?我只能说__这些都无法监听的,你想到的事件基本都不会触发__H5页面中的所以事件安静的有点可怕,这种情况也只有ios才会出现,安卓手机和鸿蒙手机都不会出现这样的情况。

    • 为了解决这种情况,我思索了很久很久差点把自己脑转晕,最后想到的解决方案是:
###### H5嵌套APP

如果嵌套ios的APP里面,当用户点击左上角返回按钮,由APP生命周期里调用H5方法,在H5中window里挂载自己写好的一个函数,当调用自己挂载的函数时发送统计上传到服务器;

###### H5嵌套小程序

如果嵌套到小程序的H5,我们不能这么写了,因为小程序没办法在页面销毁时调用H5页面的任何东西,这里不止页面销毁调不了H5方法而是任何时候都无法调用直接调H5里面的方法,所以这里我们需要使用微信提供的一个方法`` wx.miniProgram.postMessage ``<a href="https://developers.weixin.qq.com/miniprogram/dev/component/web-view.html" rel="noopener" target="_blank">文档详情</a>,我们应该怎么合理使用这个方法呢?我的想法是,每此进入需要记录时间的页面使用该方法,把需要上传的参数及时间记录并赋值给`` wx.miniProgram.postMessage({data:{}}) ``,如何当用户点击小程序原生返回时,我们可以在原生里面写一个方法用于接收该参数;
        <web-view bindmessage="bindmessage"></web-view>
        // js
        bindmessage(){
        // H5页面接收发送回来的参数
        }
        wx.miniProgram.postMessage({ data: 'foo' })

我们就可以把拿到的参数直接在小程序内完成发送统计;

总结

其实要解决这些问题也不难,难在怎么跳出思维,不能一成不变的认为只能在H5监听所有事件或者完成所有操作。
回顾一下:我们使用的主要代码有

// 在H5页面中,监听事件
document.addEventListener("visibilitychange", function() {
  if (document.visibilityState === 'visible') {
      // 页面被显示
    // backgroundMusic.play();
  } else {
      // 页面被隐藏
    // backgroundMusic.pause();
  }
});
// 用于H5页面发送给小程序的内容
wx.miniProgram.postMessage({ data: 'foo' });
// 用于iosAPP端调用的方法
window.logData = function() {};
// 小程序原生代码绑定监听H5回传参数
        <web-view bindmessage="bindmessage"></web-view>
bindmessage(){
// H5页面接收发送回来的参数
}

就这些代码,我们就完成我们想要的效果了。

创作不易,喜欢记得点赞,如有错误请评论区留言。

回到顶部