最近公司有个web项目,需要统计,突然发现百度统计中的事件已经是收费功能了。所以用JS弄一个检测埋点的功能。

1. 现代浏览器IntersectionObserver函数

这个函数在现代浏览器中已经可以使用了,在MDN上有详细的介绍,这里就不赘述了。

2. 代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function keyElementShowTrack(selector = "", threshold = 0.5) {
  // 获取目标元素
  const targetElement = document.querySelector(selector);

  // 确保目标元素存在
  if (!targetElement) {
    console.warn(`Element with selector "${selector}" not found.`);
    return;
  }

  // 创建 Intersection Observer
  const observer = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
          // 检查元素是否在视口中
          if (entry.isIntersecting) {
              console.log('Element is visible in viewport');

              // 只触发一次,之后取消观察
              observer.unobserve(entry.target);

              // 调用跟踪函数,参数为 1
              // track(1); // 假设 track 函数用于记录用户行为
          }
      });
  }, {
      root: null, // 观察视口
      rootMargin: '0px',
      threshold: threshold // 使用参数化阈值
  });

  // 开始观察目标元素
  observer.observe(targetElement);
}

在页面加载时只要执行

1
keyElementShowTrack('.keyElementClassName', 0.5)

就可以绑定监听器,当元素出现在视口中时,会触发回调函数(假设函数名称为track),然后可以在track函数中发送用户行为到服务端。

IntersectionObserver 的其他用处

例如异步加载图片,IntersectionObserver 可以用来实现懒加载,当元素出现在视口中时,才加载图片。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
document.addEventListener("DOMContentLoaded", function () {
    // 获取所有需要懒加载的图片元素
    const lazyImages = document.querySelectorAll("img.lazy");

    // 创建 Intersection Observer 实例
    const observer = new IntersectionObserver((entries, observer) => {
        entries.forEach(entry => {
            // 检查元素是否在视口中
            if (entry.isIntersecting) {
                const img = entry.target;
                // 设置图片的 src 属性
                img.src = img.dataset.src;
                // 移除懒加载类
                img.classList.remove("lazy");

                // 取消对该图片元素的观察
                observer.unobserve(img);
            }
        });
    }, {
        root: null, // 观察视口
        rootMargin: "0px",
        threshold: 0.1 // 当图片元素的 10% 可见时触发加载
    });

    // 开始观察每一个图片元素
    lazyImages.forEach(img => {
        observer.observe(img);
    });
});

然后在页面中添加一些图片元素,并使用 CSS 设置它们的 data-src 属性来指定加载的图片地址。 这样,当图片元素出现在视口中时,浏览器会自动加载对应的图片。