Quellcode durchsuchen

Merge branch 'dev-jcq' of luoy/buried-piont into master

luoyu vor 3 Wochen
Ursprung
Commit
2f067d4b8c
4 geänderte Dateien mit 80 neuen und 8 gelöschten Zeilen
  1. 25 1
      README.md
  2. 26 4
      buriedPiont.js
  3. 25 2
      vue-test/src/buriedPiont.js
  4. 4 1
      vue-test/src/components/HelloWorld.vue

+ 25 - 1
README.md

@@ -6,4 +6,28 @@
 
 #### countly: https://support.countly.com/hc/en-us/articles/360037441932-Web-analytics-JavaScript
 
-#### 以上两种方式都需要注册账号获得服务器后台,替换key值后在官网后台查看埋点数据,付费后支持自定义部署
+#### 以上两种方式都需要注册账号获得服务器后台,替换key值后在官网后台查看埋点数据,付费后支持自定义部署
+
+
+```javascrpit
+// 使用示例:
+// 【2024-06-09】以下为页面集成埋点的示例代码,支持自定义防抖间隔
+
+ import Tracker from './buriedPiont';
+ const tracker = new Tracker({
+   baseUrl: 'https://your-tracking-api.com', // 埋点上报地址
+   debounceTime: 500 // 可选,防抖间隔(毫秒),默认300ms
+ });
+ tracker.init();
+
+ 页面元素示例:
+ <button id="btn1" class="my-btn" data-track event-type="button_click">按钮1</button>
+ <button id="btn2" class="my-btn" data-track event-type="form_submit">按钮2</button>
+
+// 只要元素有 data-track 和 event-type 属性,点击时会自动触发对应事件类型的防抖上报。
+// 系统事件(如心跳、tab切换、页面关闭等)不受防抖影响,立即上报。
+
+// 更多用法详见 Tracker 类注释。
+//
+// 【2024-06-09】
+```

+ 26 - 4
buriedPiont.js

@@ -157,7 +157,6 @@ class Tracker {
     beforeDestroy: () => {}, // 销毁前的回调函数
     crashTime: 3, // 闪退阈值(几秒内关闭)
     idleTimeout: 300000, // 默认 5 分钟无操作视为离开
-    
   }
   hasInitialized = false; // 是否已初始化
   initialize(options) {
@@ -177,6 +176,8 @@ class Tracker {
     this.beforeDestroy = options.beforeDestroy || this.initCofig.beforeDestroy; // 销毁前的回调函数
     this.crashTime = options.crashTime || this.initCofig.crashTime; // 闪退阈值(几秒内关闭页面被认为是闪退)
     this.idleTimeout = options.idleTimeout || this.initCofig.idleTimeout; // 默认 5 分钟无操作视为离开
+    this.sendDataDebounceTimers = {}; // 【2024-06-09】存储每种事件类型的定时器,用于事件级防抖
+    this.debounceTime = options.debounceTime || this.debounceTime || 300; // 【2024-06-09】防抖间隔支持初始化参数传入
 
     window.JSBridge.getUserId((id) => {
       this.userId = id;
@@ -291,7 +292,7 @@ class Tracker {
     const target = event.target;
     if (target.matches('[data-track]')) {
       const trackInfo = {
-        eventType: 'button_click',
+        eventType: target.getAttribute('event-type') || 'button_click',
         elementId: target.id || '无ID',
         elementClass: target.className || '无class',
         text: target.innerText || target.textContent || '',
@@ -321,12 +322,33 @@ class Tracker {
     }
   }
   sendData(data, headers = {}) {
+    const eventType = data && data.eventType;
+    // 【2024-06-09】只对有 eventType 且不是系统事件的做防抖,系统事件立即上报
+    const systemEvents = [
+      'heartbeat', 'tab_active', 'tab_inactive', 'page_close',
+      'content_loaded', 'user_inactive', 'tracker_destroyed'
+    ];
+    if (eventType && !systemEvents.includes(eventType)) {
+      // 【2024-06-09】每种事件类型单独防抖,互不影响
+      if (this.sendDataDebounceTimers[eventType]) {
+        clearTimeout(this.sendDataDebounceTimers[eventType]);
+      }
+      this.sendDataDebounceTimers[eventType] = setTimeout(() => {
+        this._sendDataNow(data, headers);
+        this.sendDataDebounceTimers[eventType] = null;
+      }, this.debounceTime);
+    } else {
+      this._sendDataNow(data, headers);
+    }
+  }
+  _sendDataNow(data, headers = {}) {
     this.queueIdleTask(() => {
+      const UTMP = UtmTracker.get();
       const params =  {
         ...data,
-        ...UtmTracker.get()
+        ...UTMP,
+        ...UTMP.browser,
       };
-      params.browser = params.browser.browser || 'Unknown';
       console.log('上报埋点数据:', params);
       fetch(`${this.baseUrl}`, {
         method: 'POST',

+ 25 - 2
vue-test/src/buriedPiont.js

@@ -157,7 +157,7 @@ class Tracker {
     beforeDestroy: () => {}, // 销毁前的回调函数
     crashTime: 3, // 闪退阈值(几秒内关闭)
     idleTimeout: 300000, // 默认 5 分钟无操作视为离开
-    
+    debounceTime: 300, // 防抖间隔,默认300毫秒
   }
   hasInitialized = false; // 是否已初始化
   initialize(options) {
@@ -177,6 +177,8 @@ class Tracker {
     this.beforeDestroy = options.beforeDestroy || this.initCofig.beforeDestroy; // 销毁前的回调函数
     this.crashTime = options.crashTime || this.initCofig.crashTime; // 闪退阈值(几秒内关闭页面被认为是闪退)
     this.idleTimeout = options.idleTimeout || this.initCofig.idleTimeout; // 默认 5 分钟无操作视为离开
+    this.sendDataDebounceTimers = {}; // 【2024-06-09】存储每种事件类型的定时器,用于事件级防抖
+    this.debounceTime = options.debounceTime || this.debounceTime || 300; // 【2024-06-09】防抖间隔支持初始化参数传入
 
     window.JSBridge.getUserId((id) => {
       this.userId = id;
@@ -291,7 +293,7 @@ class Tracker {
     const target = event.target;
     if (target.matches('[data-track]')) {
       const trackInfo = {
-        eventType: 'button_click',
+        eventType: target.getAttribute('event-type') || 'button_click',
         elementId: target.id || '无ID',
         elementClass: target.className || '无class',
         text: target.innerText || target.textContent || '',
@@ -321,6 +323,27 @@ class Tracker {
     }
   }
   sendData(data, headers = {}) {
+    const eventType = data && data.eventType;
+
+    // 【2024-06-09】只对有 eventType 且不是系统事件的做防抖,系统事件立即上报
+    const systemEvents = [
+      'heartbeat', 'tab_active', 'tab_inactive', 'page_close',
+      'content_loaded', 'user_inactive', 'tracker_destroyed'
+    ];
+    if (eventType && !systemEvents.includes(eventType)) {
+      // 【2024-06-09】每种事件类型单独防抖,互不影响
+      if (this.sendDataDebounceTimers[eventType]) {
+        clearTimeout(this.sendDataDebounceTimers[eventType]);
+      }
+      this.sendDataDebounceTimers[eventType] = setTimeout(() => {
+        this._sendDataNow(data, headers);
+        this.sendDataDebounceTimers[eventType] = null;
+      }, this.debounceTime);
+    } else {
+      this._sendDataNow(data, headers);
+    }
+  }
+  _sendDataNow(data, headers = {}) {
     this.queueIdleTask(() => {
       const UTMP = UtmTracker.get();
       const params =  {

+ 4 - 1
vue-test/src/components/HelloWorld.vue

@@ -1,9 +1,12 @@
 <template>
  <div>
   这是一个空页面
-  <button data-track="点了按钮">
+  <button data-track="点了按钮" event-type="button_click">
    点击按钮,发送数据
   </button>
+   <a href="javascript:;" data-track="点了链接" event-type="link_click">
+   这是个链接,发送数据
+  </a>
  </div>
 </template>
 <script setup>