From 6dc3cecbc2ee6cc9e46e116752ebd90f2c309437 Mon Sep 17 00:00:00 2001 From: shengyonggen Date: Wed, 11 Apr 2018 17:26:12 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E7=A5=9E=E7=AD=96jssdk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mip-stats-sa/README.md | 72 ++++++++++++ src/mip-stats-sa/mip-stats-sa.js | 183 +++++++++++++++++++++++++++++++ src/mip-stats-sa/package.json | 14 +++ 3 files changed, 269 insertions(+) create mode 100644 src/mip-stats-sa/README.md create mode 100644 src/mip-stats-sa/mip-stats-sa.js create mode 100644 src/mip-stats-sa/package.json diff --git a/src/mip-stats-sa/README.md b/src/mip-stats-sa/README.md new file mode 100644 index 000000000..e655cbba2 --- /dev/null +++ b/src/mip-stats-sa/README.md @@ -0,0 +1,72 @@ +# mip-stats-sa + +mip-stats-sa 组件说明 +神策 jssdk ,参考完整文档[点击这里](http://www.sensorsdata.cn/manual/js_sdk.html)。 +目前事件追踪支持 `click`, `mouseup`, `load`,其它事件暂不支持。 + +标题|内容 +----|---- +类型|通用 +支持布局|responsive,fixed-height,fill,container,fixed +所需脚本|https://c.mipcdn.com/static/v1/mip-stats-sa/mip-stats-sa.js + +## 示例 + +### 1. 基本用法,引入SDK +```html + + + +``` + +其中的setconfig的值,encodeURIComponent(JSON.stringify(以下神策sdk的配置)) 以下是神策jssdk的配置项参考 +```javascript +{ + sdk_url: '/wmd/sa-sdk-javascript/src/sensorsdata.full.js', + heatmap:{}, + web_url:'http://www.aa.vb', + name: 'sa', + server_url: 'https://test111.cloud.sensorsdata.cn:4006/sa' +} +``` + +### 2. 自定义采集数据 + +可以通过 click mouseup load 方式来触发自定义采集的数据。 + +这是需要配置的值 +``` +var para = {"type":"click","data":["track", ['click_button',{button_name:'导航'}]]} +``` +#### type + +说明:对应的触发事件(load 加载触发/click 点击触发/mouseup 触发) +必填:是 +格式:字符串数组 + +#### data + +说明:用于自定义采集数据 +必填:是 +格式:字符串 + +### 注意 +第一个参数表示,神策里的方法 track setProfile 等。 +第二个参数是 arguments,比如上面的这行代码的含义表示 发送一个 click_button 的事件,同时有属性 button_name 是 导航。 + + +## 实际案例方法 + +```html + + + +
+ +``` +其中第一行表示 sdk 的配置 + +其中第二行表示在页面load后 执行代码 sa.quick('autoTrack') ,转换成的配置代码为 {type:'load',data:['quick','autoTrack']} + +同样的,如果你希望在 click 后执行, sa.track('click_button',{button_name:'nav'}) ,只需要配置如下代码 {type:'click',data:['track','click_button',{button_name:'nav'}]} + diff --git a/src/mip-stats-sa/mip-stats-sa.js b/src/mip-stats-sa/mip-stats-sa.js new file mode 100644 index 000000000..e1013363a --- /dev/null +++ b/src/mip-stats-sa/mip-stats-sa.js @@ -0,0 +1,183 @@ +/** + * @file 神策统计插件 + * @author shengyonggen + * @email 522370351@qq.com + * 参考了mip-stats-baidu的实现方式 + */ + +define(function (require) { + var util = require('util'); + var Gesture = util.Gesture; + var fn = require('util').fn; + + var customElement = require('customElement').create(); + + customElement.prototype.createdCallback = function () { + var elem = this.element; + var config = this.getConfig(); + if (config) { + + var para = config; + var n = para.name, x = null; + window['sensorsDataAnalytic201505'] = n; + if(!window[n]){ + window[n] = function(a) { + return function() { + (window[n]._q = window[n]._q || []).push([a, arguments]); + } + }; + } + var ifs = ['track','quick','register','registerPage','registerOnce','registerSession','registerSessionOnce','trackSignup', 'trackAbtest', 'setProfile','setOnceProfile','appendProfile', 'incrementProfile', 'deleteProfile', 'unsetProfile', 'identify','login','logout','clearAllRegister']; + for (var i = 0; i < ifs.length; i++) { + window[n][ifs[i]] = window[n].call(null, ifs[i]); + } + if (!window[n]._t) { + x = document.createElement('script'); + x.async = 1; + x.src = para.sdk_url; + elem.appendChild(x); + window[n].para = para; + } + this.bindEle(); + } + else { + console.warn('sensorsdata config is wrong'); + } + + }; + + customElement.prototype.getConfig = function () { + var config = {}; + var setconfig = this.element.getAttribute('setconfig'); + try { + config = decodeURIComponent(setconfig); + config = JSON.parse(config); + } catch (e) { + config = null; + } + this.saConfig = config; + return config; + }; + /** + * JSON object to Array + * + * @param {Object} configObj configObj from script has type="application/json" + * @return {Object} outConfigArray return stats array + */ + customElement.prototype.objToArray = function (configObj) { + var outConfigArray = []; + if (!configObj) { + return; + } + for (var key in configObj) { + if (configObj.hasOwnProperty(key) && Array.isArray(configObj[key])) { + configObj[key].unshift(key); + outConfigArray.push(configObj[key]); + } + } + return outConfigArray; + }; + + customElement.prototype.saSend = function (data){ + var slice = Object.prototype.toString; + if(slice.call(data) !== '[object Array]'){ + return false; + } + var type = data[0]; + var arg = data.slice(1); + var name = this.saConfig.name; + var sa = window[name]; + + sa[type].apply(sa, arg); + + } + + // 绑定事件追踪 + customElement.prototype.bindEle = function () { + + // 获取所有需要触发的dom + var tagBox = document.querySelectorAll('*[data-stats-sa-obj]'); + + for (var index = 0; index < tagBox.length; index++) { + var statusData = tagBox[index].getAttribute('data-stats-sa-obj'); + + /** + * 检测statusData是否存在 + */ + if (!statusData) { + continue; + } + + try { + statusData = JSON.parse(decodeURIComponent(statusData)); + } + catch (e) { + console.warn('事件追踪data-stats-sa-obj数据不正确'); + continue; + } + + var eventType = statusData.type; + + /** + * 检测传递数据是否存在 + */ + if (!statusData.data) { + continue; + } + + // 格式化数据 + var data = statusData.data; + + if (eventType !== 'click' && eventType !== 'mouseup' && eventType !== 'load') { + // 事件限制到click,mouseup,load(直接触发) + continue; + } + + if (tagBox[index].classList.contains('mip-stats-eventload')) { + continue; + } + + tagBox[index].classList.add('mip-stats-eventload'); + + if (eventType === 'load') { + this.saSend(data); + } + // 解决on=tap: 和click冲突短线方案 + // TODO 这个为短线方案 + else if (eventType === 'click' + && tagBox[index].hasAttribute('on') + && tagBox[index].getAttribute('on').match('tap:') + && fn.hasTouch()) { + var gesture = new Gesture(tagBox[index]); + gesture.on('tap', eventHandler); + } + else { + tagBox[index].addEventListener(eventType, eventHandler, false); + } + } + } + + // 事件触发 + function eventHandler(event) { + var tempData = this.getAttribute('data-stats-baidu-obj'); + if (!tempData) { + return; + } + var statusJson; + try { + statusJson = JSON.parse(decodeURIComponent(tempData)); + } + catch (e) { + console.warn('事件追踪data-stats-sa-obj数据不正确'); + return; + } + if (!statusJson.data) { + return; + } + + var attrData = statusJson.data; + this.saSend(attrData); + } + + return customElement; +}); diff --git a/src/mip-stats-sa/package.json b/src/mip-stats-sa/package.json new file mode 100644 index 000000000..6518b4b51 --- /dev/null +++ b/src/mip-stats-sa/package.json @@ -0,0 +1,14 @@ +{ + "name": "mip-stats-sa", + "version": "1.0.0", + "description": "神策数据 javascript sdk", + "contributors": [ + { + "name": "shengyonggen", + "email": "522370351@qq.com" + } + ], + "engines": { + "mip": ">=1.1.0" + } +} From 9b425b515a701640102e7a49f37e1fb8e203cf73 Mon Sep 17 00:00:00 2001 From: shengyonggen Date: Fri, 13 Apr 2018 11:40:12 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mip-stats-sa/README.md | 2 +- src/mip-stats-sa/mip-stats-sa.js | 86 +++++++++++++++----------------- 2 files changed, 40 insertions(+), 48 deletions(-) diff --git a/src/mip-stats-sa/README.md b/src/mip-stats-sa/README.md index e655cbba2..eaedc3721 100644 --- a/src/mip-stats-sa/README.md +++ b/src/mip-stats-sa/README.md @@ -15,7 +15,7 @@ mip-stats-sa 组件说明 ### 1. 基本用法,引入SDK ```html - + ``` diff --git a/src/mip-stats-sa/mip-stats-sa.js b/src/mip-stats-sa/mip-stats-sa.js index e1013363a..89364682b 100644 --- a/src/mip-stats-sa/mip-stats-sa.js +++ b/src/mip-stats-sa/mip-stats-sa.js @@ -4,7 +4,6 @@ * @email 522370351@qq.com * 参考了mip-stats-baidu的实现方式 */ - define(function (require) { var util = require('util'); var Gesture = util.Gesture; @@ -12,35 +11,38 @@ define(function (require) { var customElement = require('customElement').create(); - customElement.prototype.createdCallback = function () { + customElement.prototype.firstInViewCallback = function () { var elem = this.element; var config = this.getConfig(); if (config) { - - var para = config; - var n = para.name, x = null; - window['sensorsDataAnalytic201505'] = n; - if(!window[n]){ - window[n] = function(a) { - return function() { - (window[n]._q = window[n]._q || []).push([a, arguments]); - } - }; - } - var ifs = ['track','quick','register','registerPage','registerOnce','registerSession','registerSessionOnce','trackSignup', 'trackAbtest', 'setProfile','setOnceProfile','appendProfile', 'incrementProfile', 'deleteProfile', 'unsetProfile', 'identify','login','logout','clearAllRegister']; - for (var i = 0; i < ifs.length; i++) { - window[n][ifs[i]] = window[n].call(null, ifs[i]); - } - if (!window[n]._t) { - x = document.createElement('script'); - x.async = 1; - x.src = para.sdk_url; - elem.appendChild(x); - window[n].para = para; - } - this.bindEle(); - } - else { + var para = config; + var n = para.name; + var x = null; +// 使用window说明: 为了使用第三方统计神策数据JSSDK(www.sensorsdata.cn)里暴露的全局变量 + window['sensorsDataAnalytic201505'] = n; + if (!window[n]) { + window[n] = function (a) { + return function () { + window[n]._q = window[n]._q || []; + window[n]._q.push([a, arguments]); + }; + }; + } + var ifs = ['track', 'quick', 'register', 'registerPage', 'registerOnce', 'registerSession', + 'registerSessionOnce', 'trackSignup', 'trackAbtest', 'setProfile', 'setOnceProfile', 'appendProfile', + 'incrementProfile', 'deleteProfile', 'unsetProfile', 'identify', 'login', 'logout', 'clearAllRegister']; + for (var i = 0; i < ifs.length; i++) { + window[n][ifs[i]] = window[n].call(null, ifs[i]); + } + if (!window[n]._t) { + x = document.createElement('script'); + x.async = 1; + x.src = para.sdk_url; + elem.appendChild(x); + window[n].para = para; + } + this.bindEle(); + } else { console.warn('sensorsdata config is wrong'); } @@ -58,12 +60,7 @@ define(function (require) { this.saConfig = config; return config; }; - /** - * JSON object to Array - * - * @param {Object} configObj configObj from script has type="application/json" - * @return {Object} outConfigArray return stats array - */ + customElement.prototype.objToArray = function (configObj) { var outConfigArray = []; if (!configObj) { @@ -78,19 +75,17 @@ define(function (require) { return outConfigArray; }; - customElement.prototype.saSend = function (data){ + customElement.prototype.saSend = function (data) { var slice = Object.prototype.toString; - if(slice.call(data) !== '[object Array]'){ - return false; + if (slice.call(data) !== '[object Array]') { + return false; } var type = data[0]; var arg = data.slice(1); var name = this.saConfig.name; var sa = window[name]; - sa[type].apply(sa, arg); - - } + }; // 绑定事件追踪 customElement.prototype.bindEle = function () { @@ -110,8 +105,7 @@ define(function (require) { try { statusData = JSON.parse(decodeURIComponent(statusData)); - } - catch (e) { + } catch (e) { console.warn('事件追踪data-stats-sa-obj数据不正确'); continue; } @@ -150,12 +144,11 @@ define(function (require) { && fn.hasTouch()) { var gesture = new Gesture(tagBox[index]); gesture.on('tap', eventHandler); - } - else { + } else { tagBox[index].addEventListener(eventType, eventHandler, false); } } - } + }; // 事件触发 function eventHandler(event) { @@ -166,8 +159,7 @@ define(function (require) { var statusJson; try { statusJson = JSON.parse(decodeURIComponent(tempData)); - } - catch (e) { + } catch (e) { console.warn('事件追踪data-stats-sa-obj数据不正确'); return; } @@ -180,4 +172,4 @@ define(function (require) { } return customElement; -}); +}); \ No newline at end of file From 0ae44393a79e2dbeeecf7814861655169a492326 Mon Sep 17 00:00:00 2001 From: shengyonggen Date: Wed, 9 May 2018 10:54:01 +0800 Subject: [PATCH 3/4] =?UTF-8?q?1.0=E6=A0=87=E5=87=86=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mip-stats-sa/README.md | 2 +- src/mip-stats-sa/mip-stats-sa.js | 47 +++++++++++++++++--------------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/mip-stats-sa/README.md b/src/mip-stats-sa/README.md index eaedc3721..05fff62ba 100644 --- a/src/mip-stats-sa/README.md +++ b/src/mip-stats-sa/README.md @@ -36,7 +36,7 @@ mip-stats-sa 组件说明 这是需要配置的值 ``` -var para = {"type":"click","data":["track", ['click_button',{button_name:'导航'}]]} +var para = {"type":"click","data":["track", 'click_button',{button_name:'导航'}]} ``` #### type diff --git a/src/mip-stats-sa/mip-stats-sa.js b/src/mip-stats-sa/mip-stats-sa.js index 89364682b..a4145dc0f 100644 --- a/src/mip-stats-sa/mip-stats-sa.js +++ b/src/mip-stats-sa/mip-stats-sa.js @@ -4,6 +4,7 @@ * @email 522370351@qq.com * 参考了mip-stats-baidu的实现方式 */ + define(function (require) { var util = require('util'); var Gesture = util.Gesture; @@ -11,7 +12,9 @@ define(function (require) { var customElement = require('customElement').create(); - customElement.prototype.firstInViewCallback = function () { + customElement.prototype.firstInviewCallback = function () { + + var elem = this.element; var config = this.getConfig(); if (config) { @@ -89,6 +92,27 @@ define(function (require) { // 绑定事件追踪 customElement.prototype.bindEle = function () { + var me = this; + // 事件触发 + function eventHandler(event) { + var tempData = this.getAttribute('data-stats-sa-obj'); + if (!tempData) { + return; + } + var statusJson; + try { + statusJson = JSON.parse(decodeURIComponent(tempData)); + } catch (e) { + console.warn('事件追踪data-stats-sa-obj数据不正确'); + return; + } + if (!statusJson.data) { + return; + } + + var attrData = statusJson.data; + me.saSend(attrData); + } // 获取所有需要触发的dom var tagBox = document.querySelectorAll('*[data-stats-sa-obj]'); @@ -150,26 +174,5 @@ define(function (require) { } }; - // 事件触发 - function eventHandler(event) { - var tempData = this.getAttribute('data-stats-baidu-obj'); - if (!tempData) { - return; - } - var statusJson; - try { - statusJson = JSON.parse(decodeURIComponent(tempData)); - } catch (e) { - console.warn('事件追踪data-stats-sa-obj数据不正确'); - return; - } - if (!statusJson.data) { - return; - } - - var attrData = statusJson.data; - this.saSend(attrData); - } - return customElement; }); \ No newline at end of file From 14488f55ceb3d8f6f47a7413c2aebd654cfe2602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A5=20=E6=9C=88?= Date: Tue, 23 Oct 2018 18:45:35 +0800 Subject: [PATCH 4/4] Update README.md --- src/mip-stats-sa/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mip-stats-sa/README.md b/src/mip-stats-sa/README.md index 05fff62ba..5804b04c8 100644 --- a/src/mip-stats-sa/README.md +++ b/src/mip-stats-sa/README.md @@ -58,9 +58,10 @@ var para = {"type":"click","data":["track", 'click_button',{button_name:'导航' ## 实际案例方法 ```html - +// 这个代码必须放在首屏,不然不会触发 +
```