PageSourceSearch

https://northwindinnovation.xyz/static/web/js/home-ga-ctr.js?v=1.3.5

js northwindinnovation.xyz collected 2026-10-10 00:32:00 UTC 3,626 bytes, 130 lines download raw bytes

1/**
2 * GA4 首页视频 CTR 埋点
3 * 事件: home_content_view/click (常规板块), home_promo_view/click (推荐位板块)
4 * 范围: div.index-content ul.video-items div.video-item
5 * 推荐位标识: ul.video-items.home_promo
6 */
7(function () {
8  'use strict';
9
10  if (typeof gtag !== 'function') return;
11
12  var userType = window.__home_user_type__ || 'new';
13  var viewedSet = new Set();
14  var SELECTOR = 'div.index-content ul.video-items div.video-item';
15
16  /**
17   * 从 video-item 元素提取事件参数
18   * @param {Element} el - div.video-item 元素
19   * @returns {Object|null}
20   */
21  function extractMeta(el) {
22    var vid = el.dataset.vid;
23    if (!vid) return null;
24
25    var ul = el.closest('ul.video-items');
26    if (!ul) return null;
27
28    // module_name: ul 的上一个兄弟 div 中的 h2 文本
29    var moduleName = '';
30    var prev = ul.previousElementSibling;
31    if (prev) {
32      var h2 = prev.querySelector('h2');
33      if (h2) moduleName = h2.textContent.trim();
34    }
35
36    // position: li 在 ul 中的位置(从1开始)
37    var li = el.closest('li');
38    var position = 0;
39    if (li && ul) {
40      var children = ul.children;
41      for (var i = 0; i < children.length; i++) {
42        if (children[i].tagName === 'LI') {
43          position++;
44          if (children[i] === li) break;
45        }
46      }
47    }
48
49    return {
50      content_id: String(vid),
51      module_name: moduleName,
52      position: position,
53      page_name: 'homepage',
54      user_type: userType,
55      is_promo: ul.classList.contains('home_promo')
56    };
57  }
58
59  /**
60   * 根据元数据发送对应 GA4 事件
61   * @param {string} action - 'view' 或 'click'
62   * @param {Object} meta - extractMeta 返回的对象
63   */
64  function sendEvent(action, meta) {
65    var prefix = meta.is_promo ? 'home_promo_' : 'home_content_';
66    var params = {
67      content_id: meta.content_id,
68      module_name: meta.module_name,
69      position: meta.position,
70      page_name: meta.page_name,
71      user_type: meta.user_type
72    };
73    gtag('event', prefix + action, params);
74  }
75
76  /**
77   * 初始化曝光和点击追踪
78   */
79  function init() {
80    var items = document.querySelectorAll(SELECTOR);
81    if (!items.length) return;
82
83    // 曝光监听
84    if (typeof IntersectionObserver === 'function') {
85      var observer = new IntersectionObserver(function (entries) {
86        for (var i = 0; i < entries.length; i++) {
87          var entry = entries[i];
88          if (!entry.isIntersecting) continue;
89
90          var meta = extractMeta(entry.target);
91          if (!meta) continue;
92
93          var key = meta.content_id + '_' + meta.module_name + '_' + meta.position;
94          if (viewedSet.has(key)) continue;
95
96          viewedSet.add(key);
97          sendEvent('view', meta);
98          observer.unobserve(entry.target);
99        }
100      }, { threshold: 0.5 });
101
102      for (var i = 0; i < items.length; i++) {
103        observer.observe(items[i]);
104      }
105    }
106
107    // 点击监听 - 事件委托
108    var container = document.querySelector('div.index-content');
109    if (container) {
110      container.addEventListener('click', function (e) {
111        var videoItem = e.target.closest('div.video-item[data-vid]');
112        if (!videoItem) return;
113        // 确认在 video-items 列表内
114        if (!videoItem.closest('ul.video-items')) return;
115
116        var meta = extractMeta(videoItem);
117        if (meta) {
118          sendEvent('click', meta);
119        }
120      });
121    }
122  }
123
124  // DOM 就绪后初始化
125  if (document.readyState === 'loading') {
126    document.addEventListener('DOMContentLoaded', init);
127  } else {
128    init();
129  }
130})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.