ya.js 10.5 KB
/**
 * @fileoverview YAS (YOHO! Acquisition System) YOHO!采集系统的前端js的开发包,
 * 用于在网页端采集信息(应用信息,用户信息,用户行为信息,浏览器及其系统信息)。
 */
require('yoho.json2');

//工具库
var util = require('./util');

//cookie处理
var cookies = require('./cookie');

//跨域通信
var cross = require('./cross');

//事件处理
var ev = require('./event');

var config = require('./config');

//sdk 版本
var version = config.version;

var yasPath = config.yaPath;

var yasDomain = config.yasDomain;
//应用信息
var appInfo = {
  h: document.domain, //host
  p: window.location.port, //port
  u: window.location.pathname, //url
  //a:window.location.hash,//anchor
  //c:window.document.charset,//code
  ft: 0, //loadFinishTime
  fst: 0, //firstScreenTime
  // dt:document.title,//document title
  sv: '', // YAS版本
  ab: cookies('ab_5') || ''
};

//获取跟踪ID
var VisitorId = getVisitorId();

//用户信息
var custInfo = {
  ak: '',
  cd: VisitorId.cid, //client_id
  vd: (new Date().getTime() + VisitorId.cid),
  ud: '', //uid
  rf: document.referrer, //referer
  ckf: VisitorId.isNew
};

//TODO:用户操作信息  
var custOpInfo = {
  mp: '', //mouse postion
  ev: '', //event
  st: 0 //scrollTop
};

var flash = util.flashChecker();

//浏览器信息
var browserInfo = {
  sr: window.screen.width + 'x' + window.screen.height, //screenWidthxscreenHeight
  wr: window.screen.availWidth + 'x' + window.screen.availHeight, //windowWidthxwindowHeight
  sd: window.screen.colorDepth, //screenDepth
  ln: window.navigator.language ? window.navigator.language : window.navigator.browserLanguage, //language
  //bv:window.navigator.userAgent,//browserVersion
  sy: window.navigator.platform, //systemInfo
  ce: window.navigator.cookieEnabled, //cookiesEnabled
  fv: flash.f ? flash.v : 0 //flashVersion
};

//入口方法 
var _yas = function(initTime, version, tid, uid, geo, selector) {
  custInfo.ak = tid;
  appInfo.sv = version;
  custInfo.ud = uid ? uid : '';

  if (cookies('_yasgeo')) {
    var geoInfo = cookies('_yasgeo').split(',');
    custInfo.la = geoInfo[0];
    custInfo.lo = geoInfo[1];
    cookies('_yasgeo', null, {
      path: "/",
      domain: config.yasDomain,
      expires: 365 * 200
    });
  }


  var beginTime = new Date().getTime();
  var sendFlag = null;
  var isOver3sSend = false;

  appInfo.ft = beginTime - initTime;

  //firstScreenTime
  ev.addEventHandler(window, 'load', function(e) {
    var endTime = new Date().getTime();
    appInfo.fst = endTime - initTime;
    ev.removeEventHandler(window, 'load', arguments.callee);
    window.clearTimeout(sendFlag);
    if (!isOver3sSend) {
      send();
    }
  });

  sendFlag = window.setTimeout(function() {
    appInfo.fst = 0;
    appInfo.fse = '>3s';
    isOver3sSend = true;
    send();
  }, 3000);

  //记录地理信息
  if (geo) {
    util.getGeo(function(lat, lng) {
      if (lat) {
        cookies('_yasgeo', lat + ',' + lng, {
          path: "/",
          domain: yasDomain,
          expires: 365 * 200
        });
      }
    });
  }

    /**
     * 用于统计用户点击的selector元素的序号
     * 记录cookie, 待进入新页面后通过send方法将cookie中的鼠标记录发送并清空.
     *
     */
    if (selector && selector[0]) {
        for (var i = 0, length = selector.length; i < length; i++) {
            selector[i].setAttribute('yoho_index', (i +1));
        }
    } else {
        /**
         * <a>标签的点击事件,适用于页面跳转的情形
         * 记录cookie, 待进入新页面后通过send方法将cookie中的鼠标记录发送并清空.
         *
         */
        ev.addEventHandler(document, 'click', function(e) {
            e = e || window.event;
            var target = e.target || e.srcElement;
            if(target && (target.nodeName === 'A' || (target.nodeName === 'IMG' && target.parentNode.nodeName === 'A'))) {
                var pos = getMouseEventPosition(e);
                var str = pos.x + ',' + pos.y + ',' + e.type;
                var yoho_index = target.getAttribute('yoho_index') || target.parentNode.getAttribute('yoho_index');
                if (yoho_index) {
                    str += ',' + yoho_index;
                }
                cookies('_yasmp', str, {
                    path: '/',
                    domain: yasDomain,
                    expires: 365 * 200
                });
            }
            ix = 0;
        });
    }

    onerror = handleErr;
    var txt = "";

    function handleErr(msg,url,l)
    {
        txt = "This page contains error! \n\n";
        txt += "Error message is:" + msg + "\n";
        txt += "URL is: " + url + "\n";
        txt += "Line is:" + l + "\n\n";

        var errString = JSON.stringify({'er': txt});
        cookies('_yaserror', errString, {
            path: '/',
            domain: yasDomain,
            expires: 365 * 200
        });

        return false;
    }

};

function send(callback) {
    var info = util.merge(appInfo, custInfo);
    info = util.merge(info, browserInfo);

    // 鼠标位置
    var mpJson = getMousePosition();
    if (mpJson) {
        info = util.merge(info, mpJson);
        cookies('_yasmp', null, {
          path: "/",
          domain: config.yasDomain,
          expires: 365 * 200
        });
    }

    // 用户自定义信息
    var _custJsonStr = cookies('_yascustjson');
    if (_custJsonStr) {
        var custJson = JSON.parse(_custJsonStr);
        info = util.merge(info, custJson);
        cookies('_yascustjson', null, {
            path: "/",
            domain: config.yasDomain,
            expires: 365 * 200
        });
    }

    // 页面error信息
    var _yasErrorStr = cookies('_yaserror');
    if (_yasErrorStr) {
        var errorJson = JSON.parse(_yasErrorStr);
        info = util.merge(info, errorJson);
        cookies('_yaserror', null, {
            path: "/",
            domain: config.yasDomain,
            expires: 365 * 200
        });
    }

    var param = util.genParam(info);
    callback = callback ? callback : function () {
    };
    cross.imgSend(param, callback);
    var _yasev = cookies('_yasev');
    if (_yasev) {
      cross.imgSend(_yasev, function () {
        cookies('_yasev', null, {
          path: '/',
          domain: config.yasDomain,
          expires: 365 * 200
        });
      });
    }
}

function getVisitorId() {
  var cid = cookies('_yasvd');
  if (cid) {
    return {
      cid: cid,
      isNew: 'N'
    };
  }

  cid = util.Random() ^ util.hashClientInfo() & 2147483647;
  cookies('_yasvd', cid, {
    path: "/",
    domain: yasDomain,
    expires: 365 * 200
  });
  return {
    cid: cid,
    isNew: 'Y'
  };
}

function getMousePosition() {
    var mp = cookies('_yasmp');
    if (mp) {
        var mpObject = mp.split(',');
        if (mpObject.length === 3) {
            return {
                x: mpObject[0],
                y: mpObject[1],
                et: mpObject[2]
            };
        } else if (mpObject.length === 4) {
            return {
                x: mpObject[0],
                y: mpObject[1],
                et: mpObject[2],
                ix: mpObject[3]
            };
        }

    }
    return null;
}

function getMouseEventPosition(e) {
  var x = 0,
      y = 0;
   
  if (e.pageX || e.pageY) { //Chrome,Safari,FF
        x = e.pageX;
        y = e.pageY;
    }
  else if (e.clientX || e.clientY) { //IE
    x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
    y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
  }
  x -= window.screen.width/2;
  y = window.screen.height/2 - y; 
  return {
    x: x,
    y: y
  };
}

//超过5次发送自定义信息
var evTimes = 0;

//添加或发送自定义信息
_yas.add = function(trackType, input, action, label, value) {
  if (evTimes > 3) {
    cross.imgSend(cookies('_yasev'), function() {
      cookies('_yasev', null, {
        path: "/",
        domain: config.yasDomain,
        expires: 365 * 200
      });
      evTimes = 0;
      _addEv2Cookies(trackType, input, action, label, value);
    });
  } else {
    _addEv2Cookies(trackType, input, action, label, value);
  }
};

//把自定义事件信息加入cookies
function _addEv2Cookies(trackType, input, action, label, value) {
  var ev = cookies('_yasev');
  if (ev) {
    ev += '&';
  } else {
    ev = '';
  }
  cookies('_yasev', ev + 'vd=' + custInfo.vd + '&t=' + trackType + '&i=' + input + '&l=' + label + '&v=' + value, {
    path: "/",
    domain: yasDomain,
    expires: 365 * 200
  });
  evTimes++;
}

/**
 * 发送用户鼠标事件的位置, 此方法提供给用户调用, 本方法不对参数合法性进行检查, 调用者自己保证。
 * @param e 用户鼠标事件, 必选参数
 * @param flag 用户事件执行后, 页面是否停留当前页, 是可选参数
 *        true表示停留,false表示跳转, 默认值是false
 *        取值是false时, 记录cookie, 待进入新页面后通过send方法将cookie中的事件记录发送并清空。
 */
_yas.sendMouseEvent = function(e, flag) {
    e = e || window.event;
    var pos = getMouseEventPosition(e);

    if (!flag) {
        cookies('_yasmp', pos.x + ',' + pos.y + ',' + e.type, {
            path: '/',
            domain: yasDomain,
            expires: 365 * 200
        });
    } else {
        var mp = {
            x: pos.x,
            y: pos.y,
            et: e.type
        };
        var info = util.merge(appInfo, custInfo);
        info = util.merge(info, browserInfo);
        info = util.merge(info, mp);
        var param = util.genParam(info);
        cross.imgSend(param, function () {});
    }
};

/**
 * 发送用户订制信息, 此方法提供给用户调用, 本方法不对参数合法性进行检查, 调用者自己保证。
 * @param json 用户订制信息, 必选参数,采用json格式
 * @param flag 用户事件执行后, 页面是否停留当前页, 是可选参数, 默认是页面跳转
 *        true表示停留,false表示跳转, 默认值是false
 *        取值是false时, 记录cookie, 待进入新页面后通过send方法将cookie中的事件记录发送并清空。
 */
_yas.sendCustomInfo = function(json, flag) {
    if (!flag) {
        var string = JSON.stringify(json);
        cookies('_yascustjson', string, {
            path: '/',
            domain: yasDomain,
            expires: 365 * 200
        });
    } else {
        var info = util.merge(appInfo, custInfo);
        info = util.merge(info, browserInfo);
        info = util.merge(info, json);
        var param = util.genParam(info);
        cross.imgSend(param, function () {});
    }
};

module.exports = _yas;