通过Vue自定义指令实现前端埋点

在营销活动中,通过埋点可以获取用户的喜好及交互习惯,从而优化流程,进一步提升用户体验,提高转化率。

在之前的埋点方案实现中,都是在具体的按钮或者图片被点击或者被曝光时主动通过事件去上报埋点。这种方法在项目中埋点比较少时还行,一旦项目中需要大量埋点时,不可避免的要添加很多业务代码。也很大程度上造成了埋点逻辑与业务逻辑的高耦合。

为了改造这种情况,我们对于原有的埋点方式做了一些小改进,使得埋点效率得到了极大提升。

在阐述我们的埋点改造之前,有必要对埋点的一些常识做下简单的了解。

埋点上报方式都有哪些?

要知道埋点的类型有很多,上报的方式也是五花八门。前端常见的埋点方法有三种:

  • 手动埋点
  • 可视化埋点
  • 无痕埋点

手动埋点,顾名思义就是纯手动写代码,调用埋点 SDK 提供的函数,在需要埋点的业务逻辑中添加对应方法,上报埋点数据。这种也是之前一直在使用的方法。

可视化埋点是指通过可视化系统配置埋点,这种方式接触的不是很多,就不展开说了。

无痕埋点,也叫自动埋点、全埋点。即对全局所有事件和页面加载周期进行拦截埋点。

一般对哪些数据做埋点?

为了达到数据分析,便于后续的运营及产品策略调整的目的,一般需要对以下几点做埋点统计:

  • 页面埋点:统计用户进入或者离开页面的信息,如页面浏览次数(pv)、浏览页面人数(uv)、页面停留时长、设备信息等
  • 点击埋点:统计用户在页面浏览过程中触发的点击事件,如按钮、导航或者图片的点击次数
  • 曝光埋点:统计具体元素是否得到有效曝光

需求分析

本文是基于最近项目中添加埋点的需求,我们需要的一种理想化方案是:

  • 埋点与业务尽量分离,埋点逻辑更应该是独立于业务的
  • 尽量不对业务代码有侵入
  • 约定规范,通过统一收口来处理埋点逻辑

由于项目是Vue开发的,所以考虑使用自定义指令的方式来完成埋点上报。选择自定义指令的原因也是因为他能一定程度上能让业务和埋点解耦。

页面埋点在框架层面已经帮我们做掉了,这里主要关心的是点击埋点和曝光埋点。

实现思路其实也很清晰:在需要埋点的DOM节点挂载特殊属性,通过埋点SDK监听挂载了相应属性对应的事件,在事件触发时进行埋点数据上报。

那么问题来了,怎么监听呢?

对于点击事件,我们可以采用addEventListener来监听click事件。这很简单。

对于元素的曝光就稍微有点麻烦了。

首先我们来看一下为什么需要监测曝光:

为了衡量用户对产品的兴趣程度,需要计算区域的点击率(点击次数/曝光次数)。为了保证点击率的准确性,我们必须保证用户真正的浏览到了这些产品(就比如上图中最下方的机酒产品区域,由于需要滚动页面,用户才有可能看到这一区域)。

那么怎么判断元素出现在页面的可视区域呢?

按照以往的做法:监听滚动事件,通过getBoundingClientRect()方法计算监测区域与视窗的位置,然后判断元素是否出现在页面的可视区域内。但是由于scroll事件的频繁触发,性能问题很大。

基于此,浏览器特意为我们打造了一个Intersection ObserverAPI,把性能相关的细节都处理掉,让开发者只关心业务逻辑即可:

由于用户浏览页面的不确定性,还必须要避免重复的曝光行为。这个在曝光之后,移除观察即可。

代码实现

上面的需求分析还是比较抽象,下面让我们结合代码来看一下最终的实现。

Click 类封装

点击事件的处理相对比较简单,每次点击触发数据上报即可:

// src/directives/track/click.js
import { sendUBT } from "../../utils/ctrip"export default class Click {add(entry) {// console.log("entry", entry);const traceVal = entry.el.attributes["track-params"].valueconst traceKey = entry.el.attributes["trace-key"].valueconst { clickAction, detail } = JSON.parse(traceVal)const data = {action: clickAction,detail,}entry.el.addEventListener("click", function() {console.log("上报点击埋点", JSON.parse(traceVal))console.log("埋点key", traceKey)sendUBT(traceKey, data)})}
}

Exposure 类封装

曝光的相对复杂一些。

首先通过new IntersectionObserver() 实例化一个全局_observer,如果得到有效曝光的(这里当元素出现一半以上则进行曝光),就去获取 DOM 节点上的trace-key(埋点 key)和track-params(埋点 value)。

// src/directives/track/exposure.js
import "intersection-observer"
import { sendUBT } from "../../utils/ctrip"// 节流时间调整,默认100ms
IntersectionObserver.prototype["THROTTLE_TIMEOUT"] = 300export default class Exposure {constructor() {this._observer = nullthis.init()}init() {const self = this// 实例化监听this._observer = new IntersectionObserver(function(entries, observer) {entries.forEach((entry) => {// 出现在视窗内if (entry.isIntersecting) {// 获取参数// console.log("埋点节点", entry.target.attributes);const traceKey = entry.target.attributes["trace-key"].valueconst traceVal = entry.target.attributes["track-params"].valueconsole.log("traceKey", traceKey)console.log("traceVal", traceVal)const { exposureAction, detail } = JSON.parse(traceVal)const data = {action: exposureAction,detail,}// 曝光之后取消观察self._observer.unobserve(entry.target)self.track(traceKey, data)}})},{root: null,rootMargin: "0px",threshold: 0.5, // 元素出现面积,0 - 1,这里当元素出现一半以上则进行曝光})}/*** 元素添加监听** @param {*} entry* @memberof Exposure*/add(entry) {this._observer && this._observer.observe(entry.el)}/*** 埋点上报** @memberof Exposure*/track(traceKey, traceVal) {// console.log("曝光埋点", traceKey, JSON.parse(traceVal));sendUBT(traceKey, traceVal)}}

指令封装

有了点击和曝光类,下一步就是 Vue 指令的封装了,也是之所以能实现半自动埋点的核心。

这里存在一个场景就是对于同一个按钮或者图片,同时存在既需要点击埋点又需要曝光埋点的场景。所以在指令的设计时支持了单独传入和同时传入的场景:

  • v-track:click|exposure
  • v-track:exposure
// src/directives/track/index.js
import Vue from "vue"
import Click from "./click"
import Exposure from "./exposure"// 实例化曝光和点击
const exp = new Exposure()
const cli = new Click()Vue.directive("track", {bind(el, binding) {// 获取指令参数const { arg } = bindingarg.split("|").forEach((item) => {// 点击if (item === "click") {cli.add({ el })} else if (item === "exposure") {exp.add({ el })}})},
})

同时需要在src/index.js引入即可:

import "./directives/track"

使用

在需要埋点的地方使用也是很简单的:

<imgref="imageDom"trace-key="o_img"v-track:click|exposure:track-params="JSON.stringify({exposureAction: 's_pictures',clickAction: 'c_pictures',detail: {value: '测试',},})"
/>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/595197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8Spod组件

一个pod能包含几个容器 一个pause容器(基础容器/父容器/根容器&#xff09; 一个或者多个应用容器(业务容器) 通常一个Pod最好只包含一个应用容器&#xff0c;一个应用容器最好也只运行一个业务进程。 同一个Pod里的容器都是运行在同一个node节点上的&#xff0c;并且共享 net、…

javaweb学习笔记

JSP 动态网页&#xff0c;指的是随时间、地点、用户操作改变的网页 架构 CS架构 client-server 缺点&#xff1a;每一台客户端都需要安装客户端软件&#xff0c;如果升级全要升级&#xff0c;如果坏了就得维护 优点&#xff1a;响应快&#xff0c;界面美观 BS架构 browser-…

以STM32为例,实现按键的短按和长按

以STM32为例&#xff0c;实现按键的短按和长按 目录 以STM32为例&#xff0c;实现按键的短按和长按1 实现原理2 实现代码3 测试结束语 1 实现原理 简单来说就是通过设置一个定时器来定时扫描几个按键的状态&#xff0c;并分别记录按键按下的持续时间&#xff0c;通过时间的长短…

后端杂七杂八系列篇一

后端杂七杂八系列篇一 ① MySQL选择合适的数据类型① Char与Varchar② Text与Blob ② EqualsAndHashCode(callSuper true)的作用③ mybatis-plus 相关① 主键生成策略② 使用Model实现CRUD③ Wrapper的用法① Wrapper的继承关系② 项目中最常用的warpper [LambdaQueryWrapper]…

[NISACTF 2022]level-up

[NISACTF 2022]level-up wp level 1 robots.txt 通过目录爆破&#xff0c;发现存在 robots.txt 文件&#xff08;或者说查看源码&#xff0c;源码中有 disallow 提示&#xff0c;说明存在 robots.txt 文件&#xff09;&#xff1a; dirsearch -u "http://node5.anna.n…

Docker入门教程(详解)

Docker容器化 一 入门 1. 引言 &#xff08;1&#xff09;单机部署 场景&#xff1a; 将多个应用部署一台服务器上。 问题 每个应用软件&#xff0c;都会消耗物理资源&#xff0c;共用计算机资源&#xff0c;彼此之间会形成竞争关系。 &#xff08;2&#xff09;多机部署 …

python django 生鲜商城管理系统

python django 生鲜商城管理系统,包含用户端和管理端 功能&#xff1a; 用户端&#xff1a;商城主页展示&#xff0c;登录&#xff0c;注册&#xff0c;用户中心&#xff0c;购物车&#xff0c;我的订单&#xff0c;购物车结算 管理端&#xff1a;登录&#xff0c;商品&…

SpringBoot: 通过MyBatis访问ClickHouse

一、ClickHouse中建表&#xff0c;添加数据 二、SpringBoot项目添加mybatis、clickhouse、druid相关依赖 <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version></dependency>…

opencv入门到精通——Canny边缘检测

目录 理论 OpenCV中的Canny Edge检测 附加资源 在本章中&#xff0c;我们将学习 Canny边缘检测的概念 OpenCV函数: cv.Canny() 理论 Canny Edge Detection是一种流行的边缘检测算法。它由John F. Canny发明 1.这是一个多阶段算法&#xff0c;我们将经历每个阶段。 2.降…

原生JS调用OpenAI GPT接口并实现ChatGPT逐字输出效果

效果&#xff1a; 猜你感兴趣&#xff1a;springbootvue实现ChatGPT逐字输出打字效果 附源码&#xff0c;也是小弟原创&#xff0c;感谢支持&#xff01; 没废话&#xff0c;上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><me…

09、docker 安装nacos并配置mysql存储配置信息

docker 安装nacos并配置mysql存储配置信息 1、docker启动nacos的各种方式2、Docker安装nacos3、MySQL中新建nacos的数据库4、挂载数据or配置目录5、运行 1、docker启动nacos的各种方式 内嵌derby数据源 docker run -d \ -e PREFER_HOST_MODEhostname \ -e SPRING_DATASOURCE_…

软件测试技术复习点

1 术语含义&#xff08;故障、错误、失效、测试用例&#xff09; 故障&#xff08;Fault&#xff09;&#xff1a;故障是软件中的静态缺陷&#xff1b; 故障屏蔽&#xff1a;软件中的某个故障可能被其他一个或多个故障屏蔽&#xff1b; 错误&#xff08;Error&#xff09;&…

1 电科院FTU检测标准学习笔记-外观检查

作者简介&#xff1a; 本人从事电力系统多年&#xff0c;岗位包含研发&#xff0c;测试&#xff0c;工程等&#xff0c;具有丰富的经验 在配电自动化验收测试以及电科院测试中&#xff0c;本人全程参与&#xff0c;积累了不少现场的经验 目录 **前言****检测大纲****外观与结构…

LeetCode 2397. 被列覆盖的最多行数,状态压缩优化回溯法

一、题目 1、题目描述 给你一个下标从 0 开始、大小为 m x n 的二进制矩阵 matrix &#xff1b;另给你一个整数 numSelect&#xff0c;表示你必须从 matrix 中选择的 不同 列的数量。 如果一行中所有的 1 都被你选中的列所覆盖&#xff0c;则认为这一行被 覆盖 了。 形式上&am…

【目标检测实验系列】YOLOv5模型改进:融合混合注意力机制CBAM,关注通道和空间特征,助力模型高效涨点!(内含源代码,超详细改进代码流程)

自我介绍&#xff1a;本人硕士期间全程放养&#xff0c;目前成果:一篇北大核心CSCD录用,两篇中科院三区已见刊&#xff0c;一篇中科院四区在投。如何找创新点&#xff0c;如何放养过程厚积薄发&#xff0c;如何写中英论文&#xff0c;找期刊等等。本人后续会以自己实战经验详细…

开源协议简介和选择

软件国产化已经提到日程上了&#xff0c;先来研究一下开源协议。 引言 在追求“自由”的开源软件领域的同时不能忽视程序员的权益。为了激发程序员的创造力&#xff0c;现今世界上有超过60种的开源许可协议被开源促进组织&#xff08;Open Source Initiative&#xff09;所认可…

SpingBoot的项目实战--模拟电商【3.购物车模块】

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于SpringBoot电商项目的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.功能需求 二.代码编写 …

Git(2):Git环境的安装

本教程里的git命令例子都是在Git Bash中演示的&#xff0c;会用到一些基本的linux命令&#xff0c;在此为大家提前列举&#xff1a; ls/ll 查看当前目录cat 查看文件内容touch 创建文件vi vi编辑器&#xff08;使用vi编辑器是为了方便展示效果&#xff0c;学员可以记事本、edi…

使用异构图学习破解推荐系统 - 第 1 部分

Lokesh Sharma – Medium 一、说明 所以&#xff0c;这是独家新闻&#xff1a;异质图拥有一个充满潜力的世界&#xff0c;而常规图却无法做到这一点。传统的同构图很难处理不同关系和边类型的复杂性。现在是大炮的时候了——先进的架构可以解决具有多种边缘和关系类型的数据集的…

Nacos学习思维导图

一、服务注册 参考文档&#xff1a;http://www.bryh.cn/a/118936.html https://blog.csdn.net/Saintmm/article/details/121981184 二、服务续约 参考文档&#xff1a;http://www.bryh.cn/a/118936.html https://blog.csdn.net/Saintmm/article/details/121981184 三、服务…