前端埋点重要环节:如何进行精确地全局点击监听上报

模拟面试、简历指导、入职指导、项目指导、答疑解惑可私信找我~已帮助100+名同学完成改造!

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心。

背景

如果在做某个平台的时候,我们需要统计用户点击的次数,点击的区域,点击元素,等等,那我们应该怎么去做比较合适呢?

举个例子,我想在用户点击页面上的每一个元素时,我都能把这个元素的DOM节点信息记录下来,并且上报到服务器,便于后面产品那边的统计用户喜好~

公共函数?处处调用?

那我们要怎么去做呢?写一个公共函数吗?然后去统一做上报吗?

我首先写一个函数,这是一个获取点击元素信息的函数,我们可以在点击的 event 参数中拿到目标元素 target

typescript 复制代码
const reportDOM = (e: PointerEvent) => {
  // 获取到点击的目标元素
  const el = e.target
  // 把目标元素解析成字符串
  const detail = htmlElementAsString(el)
  // 进行上报
  report(detail)
}

// 上报函数
export const report = (detail) => {
  request(url, detail)
}
// 解析函数
export function htmlElementAsString(target: HTMLElement): string {
  const tagName = target.tagName.toLowerCase();
  if (tagName === 'body') {
    return '';
  }
  let classNames = target.classList.value;

  classNames = classNames !== '' ? ` class='${classNames}'` : '';
  const id = target.id ? ` id="${target.id}"` : '';
  const innerText = target.innerText;
  return `<${tagName}${id}${classNames !== '' ? classNames : ''}>${innerText}</${tagName}>`;
}

写完这几个函数之后,我们只需要在每一个点击事件中去插入这个函数即可

ts 复制代码
const click1 = (e: PointerEvent) => {
  reportDOM(e)
  
  // coding....
}
const click2 = (e: PointerEvent) => {
  reportDOM(e)
  
  // coding....
}
const click3 = (e: PointerEvent) => {
  reportDOM(e)
  
  // coding....
}

但是一个页面中,点击事件非常多啊,不可能每一个事件中去插入这个函数,非常麻烦

全局监听 + elementFromPoint

基本做法

最好的办法就是把 click 事件挂载在 window 身上,然后根据 elementFromPoint 去计算坐标匹配的元素,进行解析上报

ts 复制代码
window.addEventListener(
  'click',
  (e: PointerEvent) => {
    // 通过坐标计算出目标元素
    const el = getTargetDomByPointerEvent(e);
    if (!el) return;
    // 把目标元素解析成字符串
    const detail = htmlElementAsString(el);
    // 进行上报
    report(detail);
  },
  true,
);

// 通过坐标计算目标元素
export const getTargetDomByPointerEvent = (e: PointerEvent) => {
  const el = document.elementFromPoint(e.pageX, e.pageY);
  if (el) {
    return el as HTMLElement;
  }

  return null;
};

拓展做法,只上报所需元素

我们可以通过配置一个数组 globalClickListeners ,只对我们所需要的 DOM 节点进行监听上报,

ts 复制代码
const globalClickListeners = [
  {
    selector: '.cla', // 选择器
  },
  {
    elementText: 'report2', // 元素文本
  },
  {
    selector: '.r', // 选择器 + 元素文本
    elementText: 'report3',
  },
];

那么我们需要对 window 的点击监听进行改造

ts 复制代码
window.addEventListener(
  'click',
  (e: PointerEvent) => {
    const el = getTargetDomByPointerEvent(e);
    if (!el) return;

    if (globalClickListeners.length) {
      globalClickListeners.forEach(({ selector, elementText, data = '' }) => {
        if (selector) {
          // 选择器的情况
          const els = document.querySelectorAll(selector);
          // 点击元素是否包含所属选择器范围
          const isIncludes = [...(els as unknown as any[])].includes(el);
          // 包含则上报
          if (isIncludes) {
            const detail = htmlElementAsString(el);
            // 进行上报
            report(detail);
          }
        } else if (el.textContent === elementText) {
          // 文本相同情况
          const detail = htmlElementAsString(el);
          // 进行上报
          report(detail);
        }
      });
    }
  },
  true,
);

小结

其实上面就是埋点库中,全局点击上报的一种解决方案,看似小问题,但是其实面试了这么多人,感觉只有很少一部分人能回答的比较好~

结语 & 加学习群 & 摸鱼群

我是林三心

  • 一个待过小型toG型外包公司、大型外包公司、小公司、潜力型创业公司、大公司的作死型前端选手;
  • 一个偏前端的全干工程师;
  • 一个不正经的掘金作者;
  • 一个逗比的B站up主;
  • 一个不帅的小红书博主;
  • 一个喜欢打铁的篮球菜鸟;
  • 一个喜欢历史的乏味少年;
  • 一个喜欢rap的五音不全弱鸡

如果你想一起学习前端,一起摸鱼,一起研究简历优化,一起研究面试进步,一起交流历史音乐篮球rap,可以来俺的摸鱼学习群哈哈,点这个,有7000多名前端小伙伴在等着一起学习哦 --> 摸鱼沸点

相关推荐
majingming1234 小时前
FUNCTION
java·前端·javascript
A_nanda5 小时前
Vue项目升级
前端·vue3·vue2
SuperEugene5 小时前
Axios 接口请求规范实战:请求参数 / 响应处理 / 异常兜底,避坑中后台 API 调用混乱|API 与异步请求规范篇
开发语言·前端·javascript·vue.js·前端框架·axios
abigale036 小时前
【浏览器 API / 网络请求 / 文件处理】前端文件上传全流程:从基础上传到断点续传
前端·typescript·文件上传·vue cli
Setsuna_F_Seiei6 小时前
AI 对话应用之页面滚动交互的实现
前端·javascript·ai编程
新缸中之脑6 小时前
追踪来自Agent的Web 流量
前端
wefly20177 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
英俊潇洒美少年7 小时前
vue如何实现react useDeferredvalue和useTransition的效果
前端·vue.js·react.js
kyriewen118 小时前
给浏览器画个圈:CSS contain 如何让页面从“卡成PPT”变“丝滑如德芙”
开发语言·前端·javascript·css·chrome·typescript·ecmascript
英俊潇洒美少年8 小时前
react19和vue3的优缺点 对比
前端·javascript·vue.js·react.js