页面埋点和统计

页面埋点和统计
author: @TiffanysBear

需求背景

前端页面的展示和点击经常需要统计数据,所以在前端页面中就需要记录用户点击、浏览等的数据,通过请求的方式,上传到服务器,服务器再通过计算,统计出数据。还有些需求是需要用户操作页面,滑动到某一位置时,再进行打点统计。

实现

通过对图片的加载,将需要上报的参数通过image的src进行请求,绑定图片onload事件,发出请求。

代码实现

打点上报代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

/**
* wapfelog
*
* @class
*/
function WapFelog() {
}
var wapfelogMap = this.wapfelogMap = {};
WapFelog.prototype = {
constructor: WapFelog,
log: function (src) {
var t = new Image();
var n = 'wap_log_' + Math.floor(Math.random() * 2147483648).toString(36);
wapfelogMap[n] = t;
t.onload = t.onerror = t.onabort = function () {
// 清空事件,因为播放gif的话会多次触发onload事件
t.onload = t.onerror = t.onabort = null;
wapfelogMap[n] = null;
// 将t置为null,防止形成闭包,造成内存泄漏
t = null;
};
t.src = src;
},
send: function (type, options, bid, actId) {
var me = this;
actId = actId || 100000;
var now = new Date().getTime();
var ctjUrl = [];
// 上报统计的域名
var domain = 'https://xxx.baidu.com';
options = options || {};

ctjUrl = ctjUrl.concat([
'isSync=' + isSync,
'url=' + encodeURIComponent(location.href),
't=' + now,
'refer=' + (document.referrer ? encodeURIComponent(document.referrer) : '')
]);
if (options) {
for (var i in options) {
if (!options.hasOwnProperty(i)) {
continue;
}
ctjUrl.push(i + '=' + encodeURIComponent(options[i]));
}
}
this.log(ctjUrl.join('&'));
}
};
this.wapfelog = new WapFelog();

滑动到某一位置进行打点,监听onScroll事件,元素滑动到可视区域内时,再进行打点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function onScroll(e) {
$.each(config.elView, function (k, v) {
var $el = $(k);
$el.each(function () {
var el = this;
if (!el || !el.getBoundingClientRect) {
return;
}
// 元素顶端到可见区域顶端的距离
var top = el.getBoundingClientRect().top;
// 元素底部端到可见区域顶端的距离
var bottom = el.getBoundingClientRect().bottom;
// 浏览器可见区域高度。
var se = document.documentElement.clientHeight;
var viewed = $(el).data('viewed');
var viewLogged = $(el).data('viewLogged');
// once参数控制打点一次or重复浏览重复打点
if (v.once && viewLogged) {
return;
}
if (top < se && bottom > 0) {
if (viewed) {
return;
}
$(el).data({
viewed: true,
viewLogged: true
});
var index = $.isFunction(v.index) ? v.index.apply(el, arguments) : v.index;
var param = $.isFunction(v.param) ? v.param.apply(el, arguments) : v.param;
var cfg = $.extend(true, {}, param, {
index: index
});
wapfelog.send('pv', cfg, 1, v.actId);
}
else if (top >= se || bottom <= 0) {
$(el).data({
viewed: false
});
}
});
});
}
$(document).on('scroll.log', onScroll).trigger('scroll');