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

模拟面试、简历指导、入职指导、项目指导、答疑解惑可私信找我~已帮助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多名前端小伙伴在等着一起学习哦 --> 摸鱼沸点

相关推荐
Yvonne爱编码12 分钟前
CSS- 4.3 绝对定位(position: absolute)&学校官网导航栏实例
前端·css·html·html5·hbuilder
繁依Fanyi1 小时前
ImgShrink:摄影暗房里的在线图片压缩工具开发记
开发语言·前端·codebuddy首席试玩官
卓律涤1 小时前
【找工作系列①】【大四毕业】【复习】巩固JavaScript,了解ES6。
开发语言·前端·javascript·笔记·程序人生·职场和发展·es6
Ten peaches2 小时前
Selenium-Java版(环境安装)
java·前端·selenium·自动化
心.c2 小时前
vue3大事件项目
前端·javascript·vue.js
姜 萌@cnblogs2 小时前
【实战】深入浅出 Rust 并发:RwLock 与 Mutex 在 Tauri 项目中的实践
前端·ai·rust·tauri
蓝天白云下遛狗2 小时前
google-Chrome常用插件
前端·chrome
多多*3 小时前
Spring之Bean的初始化 Bean的生命周期 全站式解析
java·开发语言·前端·数据库·后端·spring·servlet
linweidong3 小时前
在企业级应用中,你如何构建一个全面的前端测试策略,包括单元测试、集成测试、端到端测试
前端·selenium·单元测试·集成测试·前端面试·mocha·前端面经
满怀10153 小时前
【HTML 全栈进阶】从语义化到现代 Web 开发实战
前端·html