可视化埋点平台元素曝光采集intersectionObserver的方法是什么

发布时间:2023-01-05 09:45:36 作者:iii
来源:亿速云 阅读:105

这篇文章主要介绍“可视化埋点平台元素曝光采集intersectionObserver的方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“可视化埋点平台元素曝光采集intersectionObserver的方法是什么”文章能帮助大家解决问题。

设计方案

为了快速上线第一版,笔者最初的设计方案为:

在该方案中,存在几个触发时机可能导致的问题:

测验结论

在上述逻辑成立的情况下,笔者最初的方案其实是可以正常工作,对于初次曝光,虽然发生在元素渲染到 dom 之后,但是由于会立即触发一次,故初次曝光能够正常上报。而当 dom 发生变更后,消失的元素,虽然没有调用 unobserve,但是由于该元素消失了,并不会影响后续曝光埋点的上报,所以并没有带来大的问题,而 dom 变更后,元素如果依然存在,虽然再次进行了监听,但是多次监听并不影响同一元素,所以其实也没有问题。

对于第一版,上线后也确实能够正常工作,但是对于没有 unobserve 这一点,由于 js 的垃圾回收机制,必须是没有引用后才会销毁,而没有 unobserve,那么内部必然会维护一份监听的元素的列表,保留了已经从 dom 中移除的元素的引用,从而造成内存泄漏。

故需要做一些策略来避免该问题(不然代码也会被吐槽),思路如下:

维护一份 xpath -> 元素的映射,当 dom 发生变更时,遍历所有 xpath 寻找对应的元素,

如果元素同映射中一致,那么表示该元素没有发生变更,此时可以直接忽略,什么都不做。

而如果元素发生变化,那么调用 unobserve 取消旧元素的监听,同时对新元素进行监听即可。

完整的伪代码

// 工具函数命名很清晰,含义不赘述
import { getEleByXpath, getXpathByEle, debounce } from 'utils'; 
class track {
    constructor() {
        /* 
        {
            xpath: '',
            id: ''id
        }
        */
        this.config = {} // 存储远程服务端返回的埋点 xpath 信息
        /*
            [xpath]: el,
        */
        this.map = {} // 维护的 xpath -> el 映射
        this.observer = null; // intersectionObserver 实例
    }
    // 远端获取需要曝光点的元素
    getConfig() {
        return fetch('xxx').then(res => {
            this.config = res;
            this.config.forEach(item => {
                // 初始化 xpath -> el 映射
                this.map[item.xpath] = null;
            })
        });
    }
    // 监听 dom 变更
    addDomtreeMutatorObserver() {
        // 不关心属性变化
        const config = { attributes: false, childList: true, subtree: true };
        // 监听dom变更,消个抖
        const observer = new MutationObserver(debounce(this.observe.bind(this), 200));
        observer.observe(document.body, config);
    }
    // 监听元素曝光
    observe() {
        // 此处可以加个 requestIdleCallback 来增强性能
        this.config.forEach((item) => {
            const targetEl = getEleByXpath(item.xpath);
            // 新旧元素不一致才需要取消旧元素监听,增加新元素监听
            if (targetEl !== this.map[item.xpath]) {
                // 元素存在,就监听
                if (targetEl) {
                    this.observer.observe(targetEl);
                }
                // 取消旧元素的监听
                if (this.map[shadow.xpath]) {
                    this.observer.unobserve(this.map[shadow.xpath]);
                }
                // 更新map中的el
                this.map[shadow.xpath] = targetEl;
            }
            // 一致,则什么都不做
        });
    }
    // 创建 intersectionObserver
    initObserver() {
        const callback = (entries) => {
            entries.forEach((entry) => {
                if (entry.intersectionRatio > 0.2) {
                    const targetXpath = getXpath(entry.target);
                    for (let i = 0; i < this.config.length; i++) {
                        if (this.config[i].xpath === targetXpath) {
                            // xpath一致
                            // 发送曝光埋点
                        }
                    }
                }
            });
        };
        const observer = new IntersectionObserver(callback, {
            threshold: 0.2,
        });
        this.observer = observer;
    }
    init() {
        this.getConfig().then(() => {
            // 初始化 intersectionObserver
            this.initObserver();
            // 监听元素
            this.observe();
            // 监听 dom 元素变更
            this.addDomtreeMutatorObserver();
        });
    }
}

关于“可视化埋点平台元素曝光采集intersectionObserver的方法是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。

推荐阅读:
  1. springmvc使用POJO作为参数的方法
  2. Mysql JDBC URL中重要的参数有哪些

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

intersectionobserver

上一篇:C++怎么用埃式筛法求解素数

下一篇:pycharm from lxml import etree标红问题如何解决

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》