PHP世纪论坛

 找回密码
 立即注册
搜索
查看: 335|回复: 0

关于使用JavaScript脚本记录用户鼠标点击行为

[复制链接]

32

主题

32

帖子

194

积分

新手上路

Rank: 1

积分
194
发表于 2016-3-19 18:11:26 | 显示全部楼层 |阅读模式
分析用户在网站上的行为主要有两种方式,一种较为宏观,主要是通过分析后台日志,分析用户在各个页面之间的跳转关系,另一种较为微观,主要是通过在页面上的 JavaScript 脚本记录下用户的鼠标、键盘等行为,分析用户在单个页面上的操作。本文主要是对后一种方法中的使用脚本记录用户鼠标行为的一些尝试的总结。

用户在网页上的行为是很复杂的,有很多行为(比如视线的移动)如果没有专门的设备很难取到,大多数情况下,我们能直接取到的最有价值的信息是用户鼠标的行为(当然,还有一些用户从来不用鼠标,比如盲人用户),而鼠标行为中,处理起来最为简单的是鼠标的点击。下文中,如果没有特别说明,“点击”一词指的就是鼠标点击。

我们假设,用户在一次访问会话中,点击并不是随机的,除了部分无意的点击外,大部分点击都是有意义的,表示用户对当前的区域有兴趣(哪怕是误解)。基于这个假设,记录下用户的点击行为并进行分析是有意义的,通过分析用户的点击记录,可以找出页面上吸引用户的区域,这些区域不妨称之为热区。

接下来的问题就是,对于用户的点击,我们要记录些什么以及如何记录。

一、取得点击信息

对于网页来说,用户点击的位置信息似乎是最重要的信息。当然,除此之外,还有一些其它的信息也很重要,比如点击时间、用户会话 ID、用户浏览器信息等。

使用 JavaScript,我们可以很方便地取得用户在页面上的点击事件的位置坐标。然而,在现在流行的各大主流浏览器中,这个坐标通常是相对于浏览器网页可见区域的左上角的坐标,有时页面上有滚动条,并且已经拖动了一段距离,就要再取得页面被卷去的部分的高度或宽度,以便得到点击事件距页面左上角的坐标。

这一步并不是那么简单,比如同一个网页在不同的浏览器中可能有不同的表现。当然,这个问题对于有专业前端开发人员的网站来说很容易解决(或者故意不解决)。更麻烦的是,用户的显示器分辨率不同,网页内容部分在页面中的位置也可能不同。

比如,网页内容一般有固定宽度或自适应宽度两种不同的布局方式。像淘宝首页(http://www.taobao.com/)就是固定宽度,无论你在什么分辨率的显示器下看,页面的宽度不会变化,只是页面两侧的空白不同;而亚马逊首页(http://www.amazon.com/)则是自适应宽度,在不同分辨率下,页面内容宽度会自动缩放以填满屏幕。

对于像亚马逊这样内容自适应宽度的网页,我暂时没有想到简单的处理办法,下面我们只讨论像淘宝首页这样内容固定宽度的页面。

内容固定宽度的页面根据内容在页面的位置主要有三种布局:居左、居中、居右。如下图所示。
20110319012914_ULeXT.png
三种布局记录点击位置信息的方法各不一样,原则是,记录下的位置信息应该是相对于网页内容的,与用户使用的显示器的分辨率无关。即如果用户 A 与用户 B 都点击了页面上同一个小图标,无论他们的显示器分辨率是否相同,记录下来的点击位置都应该是相同或相近的。

对于固定宽度居左的页面处理起来最为简单,因为我们能很容易取得当前点击相对于页面左上角(注意是整个页面的左上角,而不是页面可见区域的左上角)的坐标,无论用户屏幕的分辨如何,理想情况下这个坐标都是一致的,因此,直接记录点击事件相对于页面左上角的坐标就可以了。

类似地,固定宽度居右的页面处理起来也很简单,记录点击事件相对于页面右上角的坐标就可以了。不过这类布局在国内似乎很少见。

固定宽度居中的页面特殊一些,在不同浏览器下左右两侧的空白宽度不一样,因此取左上角或右上角都不合适。但只要想到,我们的坐标值其实可以是负数,就很容易解决了,可以取页面顶部中点为原点,记录点击位置相对于这个点的坐标就行了。
20110319012928_cV8iu.png
除了点击位置信息,我们经常还对另外一个信息有兴趣:当前点击是不是点在一个超链接上?一般来说,点在超链接上意味着用户将被带到另一个页面(或当前页面的另外一个部分),这对于网站方来说,是乐于看到的。而点在非超链接上意味着一次无效的点击(当然,一些网页游戏或类似应用例外),这可能是一次无意中的点击,也可能是用户以为这个地方可以点击,于是在上面点了一下,但发现什么也没有发生,这种情况通常意味着设计可能有问题。

当前点击是否点在超链接上这个信息是很有价值的。我们暂且称那些点到超链接上的点击为“有效点击”,对应地,点到非超链接上的点击为“无效点击”。这儿的有效、无效主要是指当前点击对于页面转化是否有效,并不是真正的说点到非链接区域的点击是无效或没用的,事实上,无效点击可能比有效点击更值得关注,而且更重要的是,无效点击由于没有发生页面跳转(转化),不会在服务器上留下日志记录,因此,这类点击信息只有通过网页脚本的方式来记录。

二、发送信息

记下了点击信息,如何发送出去呢?

考察了若干类似的系统,目前比较流行的方式似乎是将要发送的信息加到 URL 参数中,请求打点服务器上的一个非常小的空图片,这样,信息就将记录在打点服务器的日志(比如 apache 日志)中,之后再用专门的程序从日志中读取并分析相关信息。而且,对于打点服务器而言,由于只需要提供一个非常小的静态图片的访问,所以一台普通的服务器经过适当配置后也可以应对很高的访问量。

在 JavaScript 中,构造一个图片请求非常容易,比如:
  1. var img = new Image();
  2. img.src = "http://xxx.xxx/img.gif?a=1&b=2....";
复制代码
但这儿也有一些需要注意的地方。比如当点击在一个链接上时,页面很快就会发生跳转,而如果跳转之前 img 的请求还没有成功发出的话,这个请求就会丢失。当然,可以在发送 img 请求时设法先把页面跳转阻塞,img 请求发送完成后再继续跳转,但这种做法侵入性太高,有可能会危害用户体验,一般情况下不建议这么做。

一个减少这种情况发生的方案是,绑定 mousedown 事件而不是 click 事件,在鼠标按键按下之时即发送 img 请求。我们知道,只有在鼠标按键按下(mousedown)再弹起(mouseup)之后才是点击(click)事件(不考虑部分移动设备上的浏览器),而正常人在鼠标按下与弹起之间还有几十至一两百毫秒的时间差,有这额外的一点时间,虽然很少,但对于提高 img 请求发送的成功率来说已经很有帮助了。如果再优化一下打点服务器,让每次 img 请求响应都能尽可能快,因页面跳转发生的记录丢失就会降低很多(不过理论上还是会有一些)。

还有一个需要注意的是,在某些浏览器中,如果页面过于复杂,会频繁地触发浏览器的垃圾回收机制,如果刚好 img 又都是些没有引用的局部变量,有一些 img 就会被强制回收,请求也就发不出去了。比较好的做法是,先将 img 在某个全局变量中引用,等 img onload 或 onerror 时再将这个引用去掉。

有时也需要考虑,这一段监测用户鼠标点击行为的脚本应该放在页面的哪个位置。当然,放得越靠前越好,因为如果放得太靠后,并且网页加载速度不是很快的话,有可能监测脚本还没有加载用户就已经开始点击了,而这些点击记录显然也会丢失。但不少页面需要尽快向用户呈现首屏内容,对于这些页面来说,监测需求相对不是第一位的,监测脚本可以放到后面一些的位置。

另外,监测代码如果想写得尽量通用一些,不指定网页内容的根元素是哪一个的话(或者指定了根元素,但监测代码放在了根元素之前如 head 中),mousedown 事件基本上就要绑定到 document 对象上,这时,需要注意点击到网页滚动条上的记录是否要忽略的问题。

如何判断一个点击是否点在了页面的滚动条上是个有趣的问题,一个简单的办法是判断当前事件元素的父元素,如果这个元素的 tagName 直接就是“HTML”了,那说明当前点击到了滚动条上,不然的话,父元素应该是一个“DIV”、“BODY”之类的元素。

对于前端来说,需要做的大致就是上面这些工作了。当然,记录数据只是第一步,接下来还有漫长的数据分析过程,不过那是另外的一系列问题,以后的帖子中再继续探讨。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|PHP世纪论坛 ( 豫ICP备15004666号-2 )

GMT+8, 2018-4-20 01:11

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表