小程序从手动埋点到自动埋点的实现方法


Posted in Javascript onJanuary 24, 2019

前言

小程序由于封闭性较强,要像web应用一样实现灵活的数据收集,会有一定难度。目前开源的埋点SDK,一般采用手动埋点的方式,这种方式有较强的侵入型,为了解决这个问题就有了该文章。

手动埋点

以腾讯移动分析的SDK为例,如果要记录埋点信息,只要插入一句代码即可

// 例如,记录搜索行为
search(keyword) {
  if (keyword) {
    ...业务代码
  }
  mta.Event.stat("ico_search", {"query":keyword});
}

示例代码看起来是比较简洁的,但是埋点需要收集的数据往往不是单一的,复杂的埋点代码插入业务代码,会 影响代码的阅读体验 ,而且 埋点代码散落在各个地方,不方便管理 。

由于手动埋点必须插入到函数中,有时候我们为了获取页面某一元素点击信息,产生了一种叫无业务相关埋点,简单来说就是你的函数定义,就只有埋点代码,当这种埋点频繁出现, 代码会被严重污染 。

// wxml
<view bindtap="track">这只是一个展示view</view>
//js 
track() {
 mta.Event.stat("eleClick", {"name":xxxxx});
}

另外,由于PM会频繁调整埋点信息,而 埋点是一个繁琐又无聊的工作 ,基于Don't Repeat Yourself 原则,手动埋带要不得。

总结以上,手动埋点有下列问题

  • 影响代码的阅读体验
  • 埋点代码散落在各个地方,不方便管理
  • 代码会被污染
  • 埋点是一个繁琐又无聊的工作

自动埋点

实现思路:监听用户点击-->读取埋点配置JOSN,判断是否需要上报--> 上报数据

1、小程序监听用户点击行为

web应用监听用户点击行为是比较容易,但是小程序没有提供Dom的事件监听,不过我们可以通过事件冒泡的方式捕获。

// web监听页面点击
document.addEventListener('click',(e) => {console.log(e)})

// 小程序监听页面点击,用户的点击行为都会执行elementTracker方法
<view catchtap='elementTracker'>
 <view class='buy-now'>
   <button bindtap='buy' animation="{{scaleAnim}}">立即购票</button>
 </view>
</view>

2、判断点击位置是否落在监听元素中

假设需要监听用户是否点击class为buy-now元素,可以通过获取buy-now元素长宽,定位和点击位置坐标判断是否出现重叠,以判断是否被点击。

/**
 * 判断点击是否落在目标元素
 * @param {Object} clickInfo 用户点击坐标
 * @param {Object} boundingClientRect 目标元素信息
 * @param {Object} scrollOffset 页面位置信息
 * @returns {Boolean}
 */
export const isClickTrackArea = function (clickInfo, boundingClientRect, scrollOffset) {
  if (!boundingClientRect) return false;
  const { x, y } = clickInfo.detail; // 点击的x y坐标
  const { left, right, top, height } = boundingClientRect;
  const { scrollTop } = scrollOffset;
  if (left < x && x < right && scrollTop + top < y && y < scrollTop + top + height) {
    return true;
  }
  return false;
};

3、通过配置表声明埋点

为了解决代码入侵问题,可以将所有埋点信息统一管理,通过配置表的方式,除了方便管理,以后还可以做到动态配置,在服务端配置完毕下发到客户端。

const tracks = {
 path: 'pages/film/detail',
 elementTracks: [
  {
   element: '.buy-now', // 声明需要监听的元素
   dataKeys: ['film.filmId'], // 声明需要获取Data下的哪些数据
  },
 ]
};

4、对页面函数埋点

有些场景我们除了对页面元素点击埋点,还要对页面函数进行埋点,例如用户下拉刷新的时候,可以对原方法进行包装,插入埋点代码。

rewritePage() {
  const originPage = Page;
  Page = (page) => {
   Object.keys(page).forEach((methodName) => {
    // 执行埋点逻辑
    typeof page[methodName] === 'function' && this.recordPageFn(page, methodName);
   });
   // 执行原Page对象
   return originPage(page);
  };
 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JQuery的自定义事件代码,触发,绑定简单实例
Aug 01 Javascript
json属性名为什么要双引号(个人猜测)
Jul 31 Javascript
使用jquery清空、复位整个输入域
Apr 02 Javascript
详解JavaScript函数对象
Nov 15 Javascript
JS折半插入排序算法实例
Dec 02 Javascript
Jquery实现简单的轮播效果(代码管用)
Mar 14 Javascript
jQuery实现对无序列表的排序功能(附demo源码下载)
Jun 25 Javascript
引用jquery框架后出错的解决方法
Aug 09 Javascript
BootStrap无限级分类(无限极分类封装版)
Aug 26 Javascript
JavaScript选取(picking)和反选(rejecting)对象的属性方法
Aug 16 Javascript
JavaScript实现构造json数组的方法分析
Aug 17 Javascript
vue项目中锚点定位替代方式
Nov 13 Javascript
JavaScript递归函数定义与用法实例分析
Jan 24 #Javascript
jQuery实现当拉动滚动条到底部加载数据的方法分析
Jan 24 #jQuery
vue结合element-ui使用示例
Jan 24 #Javascript
VUE+Element环境搭建与安装的方法步骤
Jan 24 #Javascript
JS实现带阴历的日历功能详解
Jan 24 #Javascript
微信小程序webview实现长按点击识别二维码功能示例
Jan 24 #Javascript
微信小程序MUI导航栏透明渐变功能示例(通过改变rgba的a值实现)
Jan 24 #Javascript
You might like
Apache2 httpd.conf 中文版
2006/12/06 PHP
如何修改和添加Apache的默认站点目录
2013/07/05 PHP
常用PHP封装分页工具类
2017/01/14 PHP
Laravel 5.4向IoC容器中添加自定义类的方法示例
2017/08/15 PHP
Opacity.js
2007/01/22 Javascript
prototype Element学习笔记(篇二)
2008/10/26 Javascript
基于jQuery的Tab选项框效果代码(插件)
2011/03/01 Javascript
js获取多个tagname的节点数组
2013/09/22 Javascript
jQuery打印图片pdf、txt示例代码
2014/07/22 Javascript
json字符串之间的相互转换示例代码
2014/08/21 Javascript
js时间比较 js计算时间差的简单实现方法
2016/08/26 Javascript
js实现上传图片预览方法
2016/10/25 Javascript
JS刷新父窗口的几种方式小结(推荐)
2016/11/09 Javascript
原JS实现banner图的常用功能
2017/06/12 Javascript
微信小程序页面间传值与页面取值操作实例分析
2019/04/30 Javascript
JavaScript 截取字符串代码实例
2019/09/05 Javascript
js实现登录拖拽窗口
2020/02/10 Javascript
[00:43]DOTA2小紫本全民票选福利PA至宝全方位展示
2014/11/25 DOTA
[01:04]不如跳舞!DOTA2新英雄玛尔斯的欢乐日常
2019/03/11 DOTA
python扫描proxy并获取可用代理ip的实例
2017/08/07 Python
python3获取当前文件的上一级目录实例
2018/04/26 Python
python 通过麦克风录音 生成wav文件的方法
2019/01/09 Python
python 控制Asterisk AMI接口外呼电话的例子
2019/08/08 Python
关于PyTorch源码解读之torchvision.models
2019/08/17 Python
Python函数中的可变长参数详解
2019/09/12 Python
python线程join方法原理解析
2020/02/11 Python
PyCharm2020最新激活码+激活码补丁(亲测最新版PyCharm2020.2激活成功)
2020/11/25 Python
AmazeUi Tree(树形结构) 应用小结
2020/08/17 HTML / CSS
世界首屈一指的在线男士内衣权威:HisRoom
2017/08/05 全球购物
墨西哥巴士车票在线购买:ClickBus
2018/03/27 全球购物
工伤调解协议书
2016/03/21 职场文书
php字符串倒叙
2021/04/01 PHP
解决golang post文件时Content-Type出现的问题
2021/05/02 Golang
K8s部署发布Golang应用程序的实现方法
2021/07/16 Golang
Java生成日期时间存入Mysql数据库的实现方法
2022/03/03 Java/Android
经典《舰娘》游改全新动画预告 预定11月开播
2022/04/01 日漫