buriedPiont.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. class Tracker {
  2. constructor(options = {}) {
  3. this.baseUrl = options.baseUrl || '';
  4. this.timer = null;
  5. this.startTime = 0;
  6. this.heartbeatInterval = options.heartbeatInterval || 30000; // 默认30秒发送一次心跳
  7. }
  8. init() {
  9. this.startTime = Date.now();
  10. this.bindEvents();
  11. this.startHeartbeat();
  12. }
  13. bindEvents() {
  14. window.addEventListener('beforeunload', this.handleBeforeUnload);
  15. window.addEventListener('click', this.handleClickEvent);
  16. }
  17. startHeartbeat() {
  18. this.timer = setInterval(() => {
  19. this.sendData({
  20. eventType: 'heartbeat',
  21. duration: Math.round((Date.now() - this.startTime) / 1000),
  22. }, {heartbeatSeconds: this.heartbeatInterval});
  23. }, this.heartbeatInterval);
  24. }
  25. handleBeforeUnload = (e) => {
  26. const data = {
  27. eventType: 'page_close',
  28. duration: Math.round((Date.now() - this.startTime) / 1000),
  29. };
  30. const payload = JSON.stringify(data);
  31. if (navigator.sendBeacon) {
  32. navigator.sendBeacon(this.baseUrl, payload);
  33. } else {
  34. this.sendData(payload, {heartbeatSeconds: this.heartbeatInterval});
  35. }
  36. };
  37. handleClickEvent = (event) => {
  38. const target = event.target;
  39. if (target.matches('[data-track]')) {
  40. const trackInfo = {
  41. eventType: 'button_click',
  42. elementId: target.id || '无ID',
  43. elementClass: target.className || '无class',
  44. text: target.innerText || target.textContent || '',
  45. timestamp: new Date().toISOString(),
  46. };
  47. this.sendData(trackInfo, {heartbeatSeconds: this.heartbeatInterval});
  48. }
  49. };
  50. sendData(data, headers = {}) {
  51. console.log('上报埋点数据:', data);
  52. fetch(`${this.baseUrl}`, { method: 'POST', headers: { 'Content-Type': 'application/json' ,...headers}, body: JSON.stringify(data) });
  53. }
  54. destroy() {
  55. window.removeEventListener('beforeunload', this.handleBeforeUnload);
  56. window.removeEventListener('click', this.handleClickEvent);
  57. if (this.timer) {
  58. clearInterval(this.timer);
  59. }
  60. this.sendData({
  61. eventType: 'tracker_destroyed',
  62. duration: Math.round((Date.now() - this.startTime) / 1000),
  63. }, {heartbeatSeconds: this.heartbeatInterval});
  64. }
  65. }
  66. // 使用示例:
  67. // const tracker = new Tracker({ baseUrl: 'https://your-tracking-api.com' });
  68. // tracker.init();
  69. // 暴露给全局或者作为模块导出
  70. window.Tracker = Tracker;