前端项目数据埋点接入神策

介绍

应用中特定的流程收集一些信息,用来跟踪应用使用的状况,以便后续进一步优化产品或者提供运营的数据支撑。如访问数,访客,停留时常,页面浏览数等

数据收集类型

  1. 事件数据收集 页面访问量收集 使用监听url变化, 如果是history,则可以监听pushstate 和replacestate
    hashchange 页面停留时间收集
    页面停留时间,就是记录从访问页面到离开/关闭页面的时间。不管是SPA应用还是非SPA应用,都是记录从页面加载到页面关闭或跳转的时间,
    load => 单页面应用 replaceState, pushState, 非单页面应用popstate

    代码如下:

    
    // 首次进入页面 window.addEventListener("load", () => {   // 记录时间   const
    time = new Date().getTime();   dulation.startTime = time; });
    
    // 单页应用页面跳转(触发 replaceState) window.addEventListener("replaceState",
    () => {   const time = new Date().getTime();   dulation.value = time
    - dulation.startTime;
    
      // 上报   // .....
    
      // 上报后重新初始化 dulation, 以便后续跳转计算   dulation.startTime = time;  
    dulation.value = 0; });
    
    // 单页应用页面跳转(触发 pushState) window.addEventListener("pushState", () =>
    {   const time = new Date().getTime();   dulation.value = time -
    dulation.startTime;
    
      // 上报   // .....
    
      // 上报后重新初始化 dulation, 以便后续跳转计算   dulation.startTime = time;  
    dulation.value = 0; });
    
    // 非单页应用跳转触发 popstate window.addEventListener("popstate", () => {  
    const time = new Date().getTime();   dulation.value = time -
    dulation.startTime;
    
      // 上报   // .....
    
      // 上报后重新初始化 dulation, 以便后续跳转计算   dulation.startTime = time;  
    dulation.value = 0; });
    
    // 页面没有任何跳转, 直接关闭页面的情况 window.addEventListener("beforeunload", () =>
    {   const time = new Date().getTime();   dulation.value = time -
    dulation.startTime;
    
      // 上报   // .....
    
      // 上报后重新初始化 dulation, 以便后续跳转计算   dulation.startTime = time;  
    dulation.value = 0; });```
    
    ## 异常数据收集
    
    ```window.addEventListener("error", (e) => {   console.log("上报",
    "error"); });
    
    window.addEventListener("unhandledrejection", (e) => {  
    console.log("上报", "unhandledrejection"); }); ```
    

数据上报

  1. 数据格式
{
  uid; // 用户id
  title; // 页面标题
  url; // 页面的url
  time; // 触发埋点的时间
  ua; // userAgent
  screen; // 屏幕信息, 如 1920x1080
  type // 数据类型,根据触发的不同埋点有不同的类型
  data; // 根据不同的type,此处的数据也不同,如 事件数据有元素名称,事件名称、页面停留时间有停留时长....
  sdk // sdk 相关信息
}
  1. 上报方式
    一般情下使用
    XMLHttpReuqest(axios)或者Fetch,但用其有两个缺陷,一是有跨域问题,二是在页面关闭时会中断正在发送的数据。
    考虑到以上几点,一般使用图片来发送数据或者使用navigator.sendBeacon,这里就使用sendBeacon,简单方便。也可以两者结合(如果浏览器不支持sendBeancon,就使用图片的方式)。
function send(data) {
  const url = `xxxx`
  if (navigator.sendBeacon) {
    navigator.sendBeacon(url, JSON.stringify(data));
  } else {
    const imgReq = new Image();
    imgReq.src = `${url}?params=${JSON.stringify(
      data
    )}&t=${new Date().getTime()}`;
  }
}

sdk实现

// JS 完整代码部分
(function (e) {
  function wrap(event) {
    const fun = history[event];
    return function () {
      const res = fun.apply(this, arguments);

      const e = new Event(event);

      window.dispatchEvent(e);

      return res;
    };
  }

  class TrackingDemo {
    constructor(options = {}) {
      // 重写 pushState、replaceState
      window.history.pushState = wrap("pushState");
      window.history.replaceState = wrap("replaceState");

      // 上报地址
      this.reportUrl = options.reportUrl || "";
      this.sdkVersion = "1.0.0";

      this._eventList = ["click", "dblclick", "mouseout", "mouseover"];

      this._dulation = {
        startTime: 0,
        value: 0,
      };
      this._initJSError();

      // 初始化事件数据收集
      this._initEventHandler();

      // 初始化PV统计
      this._initPV();

      this._initPageDulation();
    }

    setUserId(uid) {
      this.uid = uid;
    }

    _initEventHandler() {
      this._eventList.forEach((event) => {
        window.addEventListener(event, (e) => {
          const target = e.target;
          const reportKey = target.getAttribute("report-key");
          if (reportKey) {
            this._report("event", {
              tagName: e.target.nodeName,
              tagText: e.target.innerText,
              event,
            });
          }
        });
      });
    }

    _initPV() {
      window.addEventListener("pushState", (e) => {
        this._report("pv", {
          type: "pushState",
          referrer: document.referrer,
        });
      });

      window.addEventListener("replaceState", (e) => {
        this._report("pv", {
          type: "replaceState",
          referrer: document.referrer,
        });
      });

      window.addEventListener("hashchange", () => {
        this._report("pv", {
          type: "hashchange",
          referrer: document.referrer,
        });
      });
    }

    _initPageDulation() {
      let self = this;

      function initDulation() {
        const time = new Date().getTime();
        self._dulation.value = time - self._dulation.startTime;

        self._report("dulation", {
          ...self._dulation,
        });

        self._dulation.startTime = time;
        self._dulation.value = 0;
      }

      // 首次进入页面
      window.addEventListener("load", () => {
        // 记录时间
        const time = new Date().getTime();
        this._dulation.startTime = time;
      });

      // 单页应用页面跳转(触发 replaceState)
      window.addEventListener("replaceState", () => {
        initDulation();
      });

      // 单页应用页面跳转(触发 pushState)
      window.addEventListener("pushState", () => {
        initDulation();
      });

      // 非单页应用跳转触发 popstate
      window.addEventListener("popstate", () => {
        initDulation();
      });

      // 页面没有任何跳转, 直接关闭页面的情况
      window.addEventListener("beforeunload", () => {
        initDulation();
      });
    }

    _initJSError() {
      window.addEventListener("error", (e) => {
        this._report("error", {
          message: e.message,
        });
      });

      window.addEventListener("unhandledrejection", (e) => {
        this._report("error", {
          message: e.reason,
        });
      });
    }

    // 用户可主动上报
    reportTracker(data) {
      this._report("custom", data);
    }

    _getPageInfo() {
      const { width, height } = window.screen;
      const { userAgent } = navigator;
      return {
        uid: this.uid,
        title: document.title,
        url: window.location.href,
        time: new Date().getTime(),
        ua: userAgent,
        screen: `${width}x${height}`,
      };
    }

    _report(type, data) {
      const reportData = {
        ...this._getPageInfo(),
        type,
        data,
        sdk: this.sdkVersion,
      };

      if (navigator.sendBeacon) {
        navigator.sendBeacon(this.reportUrl, JSON.stringify(reportData));
      } else {
        const imgReq = new Image();
        imgReq.src = `${this.reportUrl}?params=${JSON.stringify(
          reportData
        )}&t=${new Date().getTime()}`;
      }
    }
  }
  e.TrackingDemo = TrackingDemo;
})(window);
// HTML 代码部分
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button report-key="button">按钮</button>
</body>
<script src="./tackerDemo.js"></script>
<script>
    const trackingDemo = new TrackingDemo()
</script>
</html>

工程化

参考文档

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,根据您提供的引用内容,我无法直接回答您的问题。但是,我可以为您提供有关Angular项目神策埋点的一些信息。 神策分析是一种数据分析工具,可以帮助您跟踪和分析用户在应用程序中的行为。在Angular项目中,您可以使用神策分析来实现埋点,以便收集和分析用户的行为数据。 以下是一些实现Angular项目神策埋点的步骤: 1.安装神策分析SDK 您可以使用npm包管理器安装神策分析SDK。在终端中运行以下命令: ```shell npm install sa-sdk-javascript --save ``` 2.在Angular项目中引入SDK 在您的Angular项目中,您需要在index.html文件中引入神策分析SDK。您可以将以下代码添加到index.html文件的<head>标签中: ```html <script src="//static.sensorsdata.cn/sdk/1.15.16/sensorsdata.min.js"></script> ``` 3.初始化神策分析SDK 在您的Angular项目中,您需要初始化神策分析SDK。您可以在app.component.ts文件中添加以下代码: ```typescript import { Component } from '@angular/core'; import { Router, NavigationEnd } from '@angular/router'; declare var sensors: any; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { constructor(private router: Router) { this.router.events.subscribe(event => { if (event instanceof NavigationEnd) { sensors.track('PageView', { $url: event.urlAfterRedirects }); } }); sensors.init({ server_url: 'https://<your_server_url>.sensorsdata.cn/sa?project=<your_project>&token=<your_token>', heatmap: { clickmap: true, scroll_notice_map: true } }); } } ``` 在上面的代码中,您需要将<your_server_url>、<your_project>和<your_token>替换为您的神策分析服务器URL、项目名称和访问令牌。 4.实现埋点 在您的Angular项目中,您可以使用sensors.track()方法来实现埋点。例如,您可以在用户单击按钮时跟踪事件: ```typescript import { Component } from '@angular/core'; declare var sensors: any; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { onClick() { sensors.track('ButtonClicked', { button_name: 'my_button' }); } } ``` 在上面的代码中,当用户单击名为“my_button”的按钮时,将跟踪名为“ButtonClicked”的事件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值