愉快的展示正确的点击热力图

市面上的页面热力图大多数通过简单的基于点击XY坐标轴进行统计并展示,只能统计点击的坐标,不同的分辨率和网站布局方式(居中等)都会导致结果的不准确,并不能正确的展示被点击的元素,在页面进行改版或者布局改变时展示错误的热力图,会给行为分析提供错误的信息。

例如下面的两张图:


图1
图2


图1与图2,他们相对浏览器的XY坐标相同, 但是他们一个行为是关掉弹框,另外一个行为是点击banner图,假设一个用户点击了弹框的关闭按钮,并点击了banner图,这样两次点击会在作为热力图展示时在X:800 Y:260的点上显示被点击两次,但是你没有办法分辨到底是banner被点击两次还是弹框被关闭两次,因为他们可能忽略了被点击的坐标点的dom层级及遮挡或者隐藏。


解决办法:

    1、统计上报

    在页面被点击时获取当前事件源的dom,并获取当前的点击相对于事件源的dom的XY坐标,

    比如,当前页面结构为  html -> body -> div#app -> div.container -> div.close.  当div.close被点击时,我们获取到div.close这个元素,或获取到相对于div.close这个元素左上角的XY坐标,假设为X:0,Y:0。 这里就涉及到了, 怎样在展示的时候选取到当前点击的这个元素,我们可以通过chrome-dompath库提供的方法,获取到当前这个div.close的  js path, 类似于chrome devtools 里面的element -> copy -> js path。 这样div.close被点击时 我们需要记录两个数据, 第一个是当前元素的js path, 也就是 html -> body -> div#app -> div.container -> div.close,第二个就是相对于div.close这个元素的左上角的XY坐标,0,0。

    2、渲染展示   

    有了之前上报的数据,在需要展示时,通过浏览器打开要查看热力图的页面(这里为了环境一致,最好就是直接在浏览器通过真实的线上地址打开页面),在页面的基础上进行展示。

    拿到js path(html -> body -> div#app -> div.container -> div.close, XY坐标(0,0),  我们首先通过document.querySelector(js path)查看是否能获取到之前被点击的这个元素,不存在的原因可能有

    1)布局被改变导致元素结构不正确

    2)当前js path与统计上报时不一致

    3)或者该元素为动态渲染,当前并没有被渲染出来

    通过 js path 找不到 dom 主要包括但并不限于以上三种情况。但是任何通过 js path 找不到dom的情况 我们都可以直接不渲染,这样我们可以保证最基本的原则,不会提供错误的信息。

    在获取到正确的被点击dom之后,我们首先获取当前dom的宽高,假如该dom宽高有一项为0则可以直接不展示,因为该元素并没有真实展示在当前的页面上。

    接下来获取该dom相对于浏览器的XY坐标。根据当前我们浏览器可视窗口的大小,我们判断该dom是否在可视窗口之外。假如在可视窗口之外,我们也直接不展示。

    该dom在可视窗口之内,我们要验证该dom是否被隐藏,或者被其他元素遮挡,也就是避免dom上方有弹框或者其他场景遮挡,比如目标dom在一个自定义的scroll的box里面,而且已经被滑动到不可见的区域。这时候我们将目标dom与目标dom相对于浏览器的XY坐标使用document.elementFromPoint(x, y)返回的元素进行对比,查看通过document.elementFromPoint(x, y)选取的元素是否为目标dom。假如为目标dom则判断该dom是展示在当前页面的最上层。否则反之,该元素已经被遮挡或者不可见。

    最后该dom处于当前页面视图可见并在最上层时,我们通过该元素相对于浏览器的XY坐标。加上我们之间记录的点击时相对于目标dom左上角的XY坐标的偏移就是真实被点击的位置。

    这样我们就可以愉快的展示正确的点击热力图。


优点:

    该方法能正确展示点击热力图,做到不提供错误信息。

缺点:

    为了准确性,进行展示时需要通过 js path 获取dom进行对比等一系列操作,所以使用与用户一致的真实场景。目前我实现是使用浏览器插件对真实页面进行js注入并展示,另外的实现办法目前想到的是 也可以直接用electron 通过渲染进程打开真实场景并注入js。还有一个想法没有尝试过,在页面中 通过iframe引入页面, 并通过postMessage与探针代码通信。

    js path太长,而且太细化,导致数据很大。在渲染时性能有一定影响。(待优化)




第一次写博客,不足之处欢迎指正。

转载请注明出处

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容