在完成高端收费产品——新版大战略的时候,在最后收官阶段产品提出需对新版大战略部分功能进行埋点,意在收集用户行为信息。但是由于原先公司埋点插件并不提供批量埋点的功能,而业务所需埋的点范围较广,且所需触发元素各式各样,如有的直接静态页面,有的为异步加载页面。所以若进行单点埋的话,工作量比较大,且容易影响原有的功能。故该方案直接被PASS掉了。稍微分析了一下这些所需要处理的元素,发现其实也并不复杂。索性直接在原有的埋点基础上写了一个批量埋点的小插件,意在不影响原有功能的基础上,减少工作量。
主要实现思路如下:
鉴于各个页面所需埋的点的元素加载方式不同,有些是直接在页面上写好的元素,有些是后期通过异步加载方式渲染上去的。所以针对以上两种情况,分别采用了两种不同的方式。1、直接在页面上写好的元素。对于这种元素,直接采用了与DOM绑定的方式,简单粗暴实用。2、后期加载的元素。页面中有较大部分元素都属这类。这类元素需通过追加事件绑定加以完成。事件追加方面。为不影响元素原先事件情况下完成追加,目前做法是对元素追加的同类事件都加上命名空间,在每次追加相关埋点事件时,都清空自身该事件命名空间下已重复的事件,从而确保每个元素触发时机的唯一性。
// @charset "utf-8";
/**
* 批量埋点插件
* @create : 2016-03-16 10:02
* @author : 应杲臻<yinggaozhen@myhexin.com>
* @relyon : 需要依赖jQuery
* @usage :
* 在不影响原有功能的基础上进行批量埋点,减少工作量。
* 目前提供两种用法:
* 1、直接与DOM绑定方式,如<div ta-tag="wsddz_wsdsg_19930607"></div>;
* 直接在DOM上添加ta-tag标记即可。如果需要指定事件触发埋点,则将ta-tag更改为wsddz_wsdsg_19930607;event即可.其中event默认为click事件
* 2、调用MTA,使用MTA.mutilog方法。如MTA.mutilog(
* {
* tid : 'wsddz_wsdsg_19930607',
* el : '_pageload'
* },
* {
* tid : 'wsddz_wsdsg_19930607',
* el : '#dzl_scroll',
* e : 'scroll'
* })
*/
+(function($) {
var PAGE_TAG = '_pageload';
var LOG_TAG = 'ta-tag';
MTA = function() {};
function isExsistDom(o) {
return o == PAGE_TAG ? true : $(o).length > 0 ? true : false;
}
MTA.prototype = {
// 批量埋点
mutilog : function() {
var me = this;
// 对埋点元素进行批量追加事件
arguments = $.merge(arguments, me.getBDOM());
$.each(arguments, function(key, args) {
$(args.el).each(function(idx, nEl) {
var tmpArgs = args;
tmpArgs.el = nEl;
me.registerEvt($.extend({}, {el : '', e : 'click', tid : ''}, tmpArgs));
})
});
},
registerEvt : function(args) {
var me = this,
el = typeof args.el !== 'undefined' ? args.el : '';
if (!isExsistDom(el)) {
return;
}
if (el == PAGE_TAG) {
me.log(args.tid);
return;
}
// 对同类事件加以命名空间
$(el).off(args.e + '.ta.log').one(args.e + '.ta.log', function() {
me.log(args.tid, el);
});
},
log : function(tTid, el) {
var tid = '';
switch (typeof tTid) {
// 自定义的统计ID方法
case 'function' :
tid = tTid(el);
break;
default :
tid = tTid;
break;
}
if ($.trim(tid).length === 0) {
return;
}
// 这里是具体统计代码(略)...
},
getBDOM : function() {
return $.map($('[' + LOG_TAG + ']'), function(el) {
return {
el : el,
tid : ($(el).attr(LOG_TAG) || '').split(';')[0] || '',
e : ($(el).attr(LOG_TAG) || '').split(';')[1] || 'click'
};
});
}
};
return MTA = MTA;
}(jQuery));
感悟:
在事件处理上,为保证页面上同个元素同种事件触发的唯一性,在追加事件时,需对原先事件进行解绑。但是如果不对任何处理进行解绑的话,会把对元素原先业务上的事件也一同进行了解绑。这样就会影响具体的业务。想到了之前在研究bootstrap源码的时候,里边用到了事件命名,在之前我的一篇博客文章中也做过一点总结。试了一下,果然是我要的滑板鞋~
题外话
最近项目比较多,有段时间没写博客了,也比较无奈,PM催的急,赔了好多周末进去无偿加班(┬_┬)。身体也明显感觉变差许多,经常头昏眼花,前天又感冒了,人生多磨难啊~等把这些项目结了,要去找个茶餐厅包个包厢,去和小伙伴无忧无虑打一天的双扣。