使用 JavaScript 记录热图的用户数据
Posted
技术标签:
【中文标题】使用 JavaScript 记录热图的用户数据【英文标题】:Recording user data for heatmap with JavaScript 【发布时间】:2011-01-30 13:49:30 【问题描述】:我想知道诸如 crazyegg.com 之类的网站如何在会话期间存储用户点击数据。显然,有一些底层脚本存储了每次点击数据,但是这些数据是如何填充到数据库中的呢?在我看来,简单的解决方案是通过 AJAX 发送数据,但是当您考虑到几乎不可能设置跨浏览器页面卸载功能时,我想知道是否还有其他更高级的获取指标数据的方法。
我什至看到了一个记录每次鼠标移动的网站,我猜他们肯定不会在每次鼠标移动事件时将数据发送到数据库。
那么,简而言之,我需要什么样的技术来监控我网站上的用户活动,然后存储这些信息以创建指标数据?我不打算重新创建 GA,我只是很想知道这种事情是如何完成的。
提前致谢
【问题讨论】:
【参考方案1】:事实证明,热图分析比仅捕获光标坐标要复杂得多。有些网站是右对齐的,有些是左对齐的,有些是 100% 宽度的,有些是固定宽度的——“居中”……页面元素可以绝对定位或相对定位,浮动等。哦,还有不同的屏幕分辨率,甚至多显示器配置。
这是HeatTest 的运作方式(我是创始人之一,由于规则,必须透露):
-
javascript 处理 onClick 事件:
document.onclick = function(e)
(这不适用于 <a>
和 <input>
元素,必须自行解决)
脚本以//body/div[3]/button[id=search]
的形式记录被点击元素的XPath地址(因为坐标不可靠,见上文)和元素内的坐标。
脚本向服务器发送 JSONP 请求(由于浏览器的跨域限制,使用 JSONP)
服务器将此数据记录到数据库中。
现在,有趣的部分 - 服务器。
-
为了计算热图,服务器会在内存中启动浏览器的虚拟实例(我们使用 Chromium 和 IE9)
呈现页面
截屏,
查找元素的坐标,然后构建热图。
这需要大量的 cpu-power 和 memory 使用。 很多。因此,包括我们和 CrazyEgg 在内的大多数热图服务都有用于此任务的虚拟机和云服务器堆栈。
【讨论】:
你能详细说明一下#1吗?为什么不能在 input/a 等可点击元素上工作? @EugeneMyunster 抱歉刚刚看到你的评论。它不适用于<a>
,因为浏览器会跟随链接! :) 并卸载页面。因此,您将没有时间完成脚本的执行。 PS。顺便说一句,我们现在已经“取消”了这个项目。
我相信如果有人使用stopPropagation
也行不通?我还想知道你是如何监听所有事件的?所有事件侦听器(单击、鼠标移动等)是否仅放置在 document
上?我问这个是因为我在一次采访中被问到这个问题,当我谈到这种方法时,面试官说这不是我想要的,所以我相信有一种更有效的方法来跟踪所有事件?【参考方案2】:
许多跟踪系统使用的基本思想是使用一个 1x1px 的图像,该图像是通过额外的 GET 参数请求的。该请求被添加到服务器日志文件中,然后处理日志文件以生成一些统计信息。 所以一个极简的点击跟踪函数可能看起来像这样:
document.onclick = function(e)
var trackImg = new Image();
trackImg.src = 'http://tracking.server/img.gif?x='+e.clientX+'&y='+e.clientY;
AJAX 不会有用,因为它受同源策略的约束(您将无法向跟踪服务器发送请求)。而且您必须将 AJAX 代码添加到您的跟踪脚本中。 如果您想发送更多数据(如光标移动),您可以将坐标存储在变量中,并定期轮询 GET 参数中更新路径的新图像。
现在有很多很多问题:
跨浏览器兼容性 - 要使上述功能在所有重要的浏览器中工作,您可能需要再添加 20 行代码 获取有用的数据 许多页面都是固定宽度、居中的,因此原始 X 和 Y 坐标不会让您在页面上创建视觉叠加层 某些页面具有液体宽度元素,或使用最小和最大高度的组合 用户可以使用不同的字体大小 响应用户操作而出现在页面上的动态元素 等。等当您制定好跟踪脚本后,您只需要创建一个工具来获取原始服务器日志并将它们转换为闪亮的热图 :)
【讨论】:
感谢您的回复,非常有帮助。【参考方案3】:不知道 crazyegg 的具体实现细节,但我的做法是将鼠标事件存储在一个数组中,我会通过 AJAX 定期将其发送到后端——例如捕获的鼠标事件每 30 秒收集一次并发送到服务器。这减轻了为每个事件创建请求的压力,但它也确保我最多只会丢失 30 秒的数据。您还可以将发送添加到卸载事件,这会增加您获得的数据量,但您不会依赖它。
我将如何实现它的一些示例(使用 jQuery 作为我的香草 JS 技能有点生疏):
$(function()
var clicks = [];
// Capture every click
$().click(function(e)
clicks.push(e.pageX+','+e.pageY);
);
// Function to send clicks to server
var sendClicks = function()
// Clicks will be in format 'x1,y1;x2,y2;x3,y3...'
var clicksToSend = clicks.join(';');
clicks = [];
$.ajax(
url: 'handler.php',
type: 'POST',
data:
clicks: clicksToSend
);
// Send clicks every 30 seconds and on page leave
setInterval(sendClicks, 30000);
$(window).unload(sendClicks);
);
请注意,我没有以任何方式测试或尝试过这个,但这应该会给你一个大致的想法。
【讨论】:
【参考方案4】:我真的不明白为什么你认为不可能将一个用户会话中的所有点击点存储到数据库中?
他们的宗旨是“查看人们点击的位置” 一旦收集到足够的数据,就很容易在批处理中制作热图。
人们真的低估了数据库、索引和分片。这里唯一困难的是为底层架构筹集足够的资金:)
【讨论】:
【参考方案5】:如果您只是在寻找互动,您可以将您的 <input type="button">
替换为 <input type="image">
。这些会自动提交用户点击位置的 X、Y 坐标。
jQuery 还有一个很好的mousemove event binding 实现,可以跟踪当前鼠标位置。我不知道你想要的最终结果,但你可以 setTimeOut(submitMousePosition, 1000) 每秒发送一个带有鼠标位置的 ajax 调用或类似的东西。
【讨论】:
以上是关于使用 JavaScript 记录热图的用户数据的主要内容,如果未能解决你的问题,请参考以下文章