网站分析统计JS源码分享
之前公司做了一个分析云平台,用来跟踪收集海量的用户行为的相关数据,供运营人员实时监控网站访问量,统计PV,UV,独立IP,访问时段,访问时长,热点追踪等多类信息,我用JS写了一个小插件,只需要再页面加载这个js文件即可,供有需要的朋友参考,该插件分为两部分组成,一部分是分析的主JS,另一部分功能是用来提供热点地图绘制信息。
/**
* 分析主JS,该JS部署时放在页面</boday>标签之前,所有引入的其他JS位置之后
* 该JS文件会自动加载hot.js文件,进行行为追踪,无需配置。
* 配置说明:
* 如果追踪页面加载速度,需要在页面标签<head>内靠前位置Javascript语句块中嵌入代码: var _speedMark = new Date(); 如不配置,该功能不可用,这种方式实现比较传统,为的是兼容更多的浏览器,如果只考虑高版本的浏览器,可以用很简单很直接的方式来解决。这里就不累赘讲述了。
*/
/**************************参数说明********************************
*
* bs 浏览器及版本,中间固定用“/”隔开: 如 Firefox/29
* fl Flash版本:如 13.0 r0
* hp 是否设置为首页,y表是,否则为空
* jv 是否禁用脚本:0表否,1表是
* lg 浏览器语言:如 zh-cn
* ps 页面加载用时:如 271 单位为毫秒,如没配置该属性,ps没值,网页首次加载有值,其它情况下值为0
* pvi 用户标识:如 5699369775 第一次访问页面时产生,只要用户不清除客户端cookie,该值永远存在
* rurl 上一个页面地址
* scl 屏幕颜色深度:如 24-bit
* scr 屏幕分辨率: 如 1600x900
* sh 滚动条可滚动高度:如 3259
* si 本地一次会话标识: 如 s479879256
* tz 区时:如 8
* ui 登陆的用户ID,未登陆时没有该值:如 7155113994790596
* url 当前的URL
* x 鼠标点击事件时,相对body中轴线的x坐标, 中轴线左边为负,右边为正,此值只有开启热点追踪时才会产生,页面初始化时无值
* y 鼠标点击事件时的y坐标,此值只有开启热点追踪时才会产生,页面初始化时无值
*
**************************参数说明********************************/
/**************************使用方法********************************
*
* 配置方式:
* 在页面</body>标签之前其他外部文件引入之后的位置加入该js引用
*
* <script type="text/javascript" src ="ea.js" > </script>
*
**************************使用方法********************************/
; (function () {
function ea() {
this.url = [];
this.init()
}
var h, k, j, l, p, r, q, n, m, o,
f = {};
ea.prototype = {
init: function () {
f ? l = f : l = {};
h = document;
k = h.location;
j = h.body;
m = navigator;
p = m.platform;
q = this.getCookieSetDomain();
},
run: function () {
g.init();
this.url.push(this.getUrl());
this.url.unshift("http://180.163.187.8:1080/go.php?");
this.url.push(this.getRefInfo());
this.url.push(this.getPvi());
this.url.push(this.getSi());
this.url.push(this.getMainEnvInfo());
this.url.push(this.getExtendEnvInfo());
this.url.push(this.getBrowserInfo());
this.url.push(this.getPageSpeed());
this.url.push(this.getScrollHeight());
this.url.push(this.getUi());
g.save();
this.sendInfo(this.url.join(""));
//this.loadHotClick(this);
},
loadHotClick: function (a) {
u && u.getScript({
url: "hot.js",
callback: function () {
(new hot(a)).watchClick();
}
})
},
inArray: function (a, c) {
for (i = 0; i < a.length && a[i] != c; i++);
return i != a.length;
},
getUi: function () {
var a = "",
b = "";
a = unescape(g.get("pi=", !0));
if ("-" != a) {
for (var a = a.split(";"), c = 0; c < a.length; c++) {
b = a[c];
break;
}
}
return "&ui=" + b;
},
getUrl: function () {
return "&url=" + escape(h.URL);
},
getRefInfo: function () {
return "&rurl=" + escape(h.referrer.substr(0, 100));
},
getPageSpeed: function () {
return "undefined" == typeof _speedMark ? "&ps=" : "&ps=" + (new Date - _speedMark);
},
getPvi: function () {
try {
return m.cookieEnabled ? "&pvi=" + g.setCookie("pgv_pvi", !0) : "&pvi=NoCookie";
} catch (a) {
return "&pvi=NoCookie";
}
},
getSi: function () {
return "&si=" + g.setCookie("ssi");
},
getBrowserInfo: function () {
var a = b.detect();
return "&os=" + a.os + "&bs=" + a.browser + "/" + a.version;
},
getScrollHeight: function () {
return "&sh=" + Math.max(j.scrollHeight, h.documentElement.scrollHeight);
},
getMainEnvInfo: function () {
var a = "";
try {
var c = "-",
b = "-",
d = "-",
e = "-",
o = 0;
self.screen && (c = screen.width + "x" + screen.height, b = (screen.colorDepth || 0) + "-bit");
m.language ? d = m.language.toLowerCase() : m.browserLanguage && (d = m.browserLanguage.toLowerCase());
o = m.javaEnabled() ? 1 : 0;
e = -((new Date).getTimezoneOffset()) / 60;
a = "&scr=" + c + "&scl=" + b + "&lg=" + d + "&jv=" + o + "&tz=" + e
} catch (g) { } finally {
return a
}
},
getExtendEnvInfo: function () {
var a = "";
try {
var c = k.href,
b = "",
a = a + ("&fl=" + this.getFlashInfo());
j.addBehavior && (j.addBehavior("#default#homePage"), j.isHomePage(c) && (a += "&hp=y")) || (a += "&hp=");
j.addBehavior && (j.addBehavior("#default#clientCaps"), b = j.connectionType);
} catch (d) { } finally {
return a
}
},
getFlashInfo: function () {
var a = "-",
c = navigator;
try {
if (c.plugins && c.plugins.length)
for (var b = 0; b < c.plugins.length; b++) {
if (-1 < c.plugins[b].name.indexOf("Shockwave Flash")) {
a = c.plugins[b].description.split("Shockwave Flash ")[1];
break
}
} else if (window.ActiveXObject)
for (b = 12; 5 <= b; b--) try {
if (eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash." +
b + "');")) {
a = b + ".0";
break
}
} catch (d) { }
} catch (e) { }
return a
},
getParameter: function (a, c) {
if (a && c) {
var b = c.match(RegExp("(\\?|#|&)" + a + "=([^&^#]*)(#|&|$)"));
return b ? b[2] : ""
}
return ""
},
getCookieSetDomain: function () {
var a =
window.location.host,
c = {
"com.cn": 1,
"net.cn": 1,
"gov,cn": 1,
"com.hk": 1
},
b = a.split(".");
2 < b.length && (a = (c[b.slice(-2).join(".")] ? b.slice(-3) : b.slice(-2)).join("."));
return a
},
sendInfo: function (a) {
n = new Image(1, 1);
n.onload = n.onerror = function () {
n.onload = n.onerror = null;
n = null;
}
n.src = a;
}
};
var u = {
config: {
url: "",
charset: "utf-8",
callback: function () { }
},
merge: function (a, c) {
for (var b in c) a[b] = c[b];
return a
},
getScript: function (a) {
var c;
this.config = this.merge(this.config, a);
a = document.createElement("script");
a.setAttribute("type", "text/javascript");
a.setAttribute("charset", this.config.charset);
a.setAttribute("src", this.config.url);
var b = document.getElementsByTagName("script")[0];
b.parentNode.insertBefore(a, b);
c = this.config.callback;
a.onload = a.onreadystatechange = function () {
("undefined" == typeof this.readyState || "loaded" == this.readyState || "complete" == this.readyState) && c()
}
}
},
d = {
GetRandomNum: function (a, b) {
var g = b - a;
var r = Math.random();
return (a + Math.round(r * g));
}
},
g = {
sck: [],
sco: {},
init: function () {
var a = this.get("pgv_info=", !0);
if ("-" != a) {
for (var a = a.split("&"), c = 0; c < a.length; c++) {
var b = a[c].split("=");
this.set(b[0], unescape(b[1]))
}
}
},
get: function (a, c) {
var b = c ? h.cookie : this.get("pgv_info=", !0),
d = "-",
e;
e = b.indexOf(a);
if (-1 < e) {
e += a.length;
d = b.indexOf(";", e); -1 == d && (d = b.length);
if (!c) {
var f = b.indexOf("&", e); -1 < f && (d = Math.min(d, f))
}
d = unescape(b.substring(e, d))
}
return d
},
set: function (a, c) {
this.sco[a] = c;
for (var b = !1, d = this.sck.length, e = 0; e < d; e++)
if (a == this.sck[e]) {
b = !0;
break
}
b || this.sck.push(a)
},
setCookie: function (a, c) {
var b = g.get(a + "=", c);
if ("-" == b) {
c ? b = "" : b = "s";
var d = (new Date).getUTCMilliseconds(),
b = b + Math.round(2147483647 * Math.abs(Math.random() + 1)) * (d + 1) % 1E10
}
c ? this.saveCookie(a + "=" + b, "expires=Sun, 18 Jan 2038 00:00:00 GMT;") : this.set(a, b);
return b
},
save: function () {
if (l.sessionSpan) {
var a = new Date;
a.setTime(a.getTime() + 6E4 * l.sessionSpan)
}
for (var c = "", b = this.sck.length, d = 0; d < b; d++) c += this.sck[d] + "=" + this.sco[this.sck[d]] + "&";
c = "pgv_info=" + c.substr(0, c.length - 1);
b = "";
a && (b = "expires=" + a.toGMTString());
this.saveCookie(c, b)
},
saveCookie: function (a, c) {
h.cookie = a + ";path=/;domain=" + q + ";" + c
}
},
b = {
detect: function () {
var ret = {
browser: this.search(this.data.bs),
version: this.search(navigator.userAgent),
os: this.search(this.data.os)
};
if (ret.os == 'Linux') {
var distros = ['CentOS', 'Debian', 'Fedora', 'Gentoo', 'Mandriva', 'Mageia', 'Red Hat', 'Slackware', 'SUSE', 'Turbolinux', 'Ubuntu'];
for (var i = 0; i < distros.length; i++) {
if (navigator.userAgent.toLowerCase().match(distros[i].toLowerCase())) {
ret.distro = distros[i];
break;
}
}
}
return ret;
},
search: function (data) {
if (typeof data === "object") {
for (var i = 0; i < data.length; i++) {
var dataString = data[i].string,
dataProp = data[i].prop;
this.version_string = data[i].versionSearch || data[i].identity;
if (dataString) {
if (-1 != dataString.indexOf(data[i].subString)) {
return data[i].identity;
}
} else if (dataProp) {
return data[i].identity;
}
}
} else {
var index = data.indexOf(this.version_string);
if (index == -1) return;
return parseFloat(data.substr(index + this.version_string.length + 1));
}
},
data: {
bs: [
{ string: navigator.userAgent, subString: "Chrome", identity: "Chrome" },
{ string: navigator.userAgent, subString: "OmniWeb", versionSearch: "OmniWeb/", identity: "OmniWeb" },
{ string: navigator.vendor, subString: "Apple", identity: "Safari", versionSearch: "Version" },
{ prop: window.opera, identity: "Opera", versionSearch: "Version" },
{ string: navigator.vendor, subString: "iCab", identity: "iCab" },
{ string: navigator.vendor, subString: "KDE", identity: "Konqueror" },
{ string: navigator.userAgent, subString: "Firefox", identity: "Firefox" },
{ string: navigator.vendor, subString: "Camino", identity: "Camino" },
{ string: navigator.userAgent, subString: "Netscape", identity: "Netscape" },
{ string: navigator.userAgent, subString: "MSIE", identity: "Explorer", versionSearch: "MSIE" },
{ string: navigator.userAgent, subString: "Gecko", identity: "Mozilla", versionSearch: "rv" },
{ string: navigator.userAgent, subString: "Mozilla", identity: "Netscape", versionSearch: "Mozilla" }
],
os: [
{ string: navigator.platform, subString: "Win", identity: "Windows" },
{ string: navigator.platform, subString: "Mac", identity: "Mac" },
{ string: navigator.userAgent, subString: "iPhone", identity: "iPhone/iPod" },
{ string: navigator.userAgent, subString: "iPad", identity: "iPad" },
{ string: navigator.userAgent, subString: "Android", identity: "Android" },
{ string: navigator.platform, subString: "Linux", identity: "Linux" }
]
}
};
ea && (new ea).run();
})();
第二部分,热点追踪,主要记录鼠标操作的页面位置信息,通过主jS自动加载,当然需要配置,如果不要记录热点追踪,可以在上面主JS配置不要加载。
以下是hot.js文件的内容
/**
* 热点跟踪js,将通过ea.js按需加载,目前限制了整个文档跟踪,仅仅跟踪html文档中以下几种标签类型:"A"/"IMG"/"INPUT"/"BUTTON"/"SELECT"/"OBJECT"/"TEXTAREA"/"EMBED"
*/
function hot(a) {
this.t = a
}
hot.prototype = {
sendHeat: function (a) {
var b, d = [],
q = document.body,
s = document.documentElement;
if (a.r && 1 == a.r) {
d.push("&x=" + a.x);
d.push("&y=" + a.y);
a = this.t.url.join("") + d.join("");
b = this.t.getParameter("ps", a);
a = a.replace("ps=" + b, "" == b ? "ps=" : "ps=0");
a = a.replace("sh=" + b, "sh=" + Math.max(q && q.scrollHeight, s && s.scrollHeight));
this.t.sendInfo(a);
}
},
getPos: function (a, d, b, c) {
var b = b || 0,
c = c || 0,
d = d || document,
e = a || window.event,
t = e.srcElement || e.target,
r = 0,
a = {},
a = e.pageX || e.pageY ? {
x: e.pageX,
y: e.pageY
} : {
x: e.clientX + Math.max(d.documentElement.scrollLeft, d.body.scrollLeft) - d.body.clientLeft,
y: e.clientY + Math.max(d.documentElement.scrollTop, d.body.scrollTop) - d.body.clientTop
};
a.x += b;
a.y += c;
d = Math.max(Math.max(document.body.clientWidth, document.body.offsetWidth), Math.max(document.body.scrollWidth, document.documentElement.scrollWidth)) / 2;
a.x = a.x - d + window.screen.width / 2 - (Math.max(document.body.scrollHeight, document.documentElement.scrollHeight) > ("undefined" == typeof window.innerHeight ? document.documentElement.clientHeight : window.innerHeight) ? 8.5 : 0);
a.x = a.x > d ? a.x - d : -(d - a.x);
switch (t.tagName) {
case "A":
case "IMG":
case "INPUT":
case "EMBED":
case "BUTTON":
case "SELECT":
case "OBJECT":
case "TEXTAREA":
a.r = 1;
break;
default:
a.r = r;
}
return a
},
clickHeat: function (a) {
this.sendHeat(this.getPos(a))
},
watchClick: function (a) {
var d = function (a, b, c) {
var d = function (a) {
a = window.event || a;
target = a.srcElement || a.target;
c(a, target)
};
a.attachEvent ? a.attachEvent("on" + b, d) : a.addEventListener(b, d, !1)
},
b = this;
if (a) b.clickHeat(evt);
else {
a = document;
d(a, "click", function (a) {
b.sendHeat(b.getPos(a))
});
for (var c = a.getElementsByTagName("iframe"), e = 0, a = c.length; e < a; e++) try {
(function () {
var a = c[e],
f = a.contentWindow.document;
d(f, "click",
function (d) {
var c = b.getElementPos(a);
b.sendHeat(b.getPos(d, f, c.x, c.y))
})
})()
} catch (f) { }
}
},
getElementPos: function (a) {
if (null === a.parentNode || "none" == a.style.display) return !1;
var d = navigator.userAgent.toLowerCase(),
b = null,
c = [];
if (a.getBoundingClientRect) return d = a.getBoundingClientRect(), a = Math.max(document.documentElement.scrollTop, document.body.scrollTop), b = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft), {
x: d.left + b - document.body.clientLeft,
y: d.top + a - document.body.clientTop
};
if (document.getBoxObjectFor) d = document.getBoxObjectFor(a), c = [d.x - (a.style.borderLeftWidth ? Math.floor(a.style.borderLeftWidth) : 0), d.y - (a.style.borderTopWidth ? Math.floor(a.style.borderTopWidth) : 0)];
else {
c = [a.offsetLeft, a.offsetTop];
b = a.offsetParent;
if (b != a)
for (; b;) c[0] += b.offsetLeft, c[1] += b.offsetTop, b = b.offsetParent;
if (-1 < d.indexOf("opera") || -1 < d.indexOf("safari") && "absolute" == a.style.position) c[0] -= document.body.offsetLeft, c[1] -= document.body.offsetTop
}
for (b = a.parentNode ? a.parentNode : null; b && "BODY" !=
b.tagName && "HTML" != b.tagName;) c[0] -= b.scrollLeft, c[1] -= b.scrollTop, b = b.parentNode ? b.parentNode : null;
return {
x: c[0],
y: c[1]
}
}
};
window.hot = hot;
网站分析统计JS源码分享的更多相关文章
- vue源码分析—Vue.js 源码构建
Vue.js 源码是基于 Rollup 构建的,它的构建相关配置都在 scripts 目录下.(Rollup 中文网和英文网) 构建脚本 通常一个基于 NPM 托管的项目都会有一个 package.j ...
- vue源码分析—Vue.js 源码目录设计
Vue.js 的源码都在 src 目录下,其目录结构如下 src ├── compiler # 编译相关 ├── core # 核心代码 ├── platforms # 不同平台的支持 ├── ser ...
- “限时分享“ 本地80个小游戏 HTML+CSS+JS源码分享
里面有80款小游戏源码,支持内置导航,可以拿来练手或者消磨时间,具体功能以及游戏请看下图 维京战争小游戏源码 链接:https://pan.baidu.com/s/ ...
- basket.js 源码分析
basket.js 源码分析 一.前言 basket.js 可以用来加载js脚本并且保存到 LocalStorage 上,使我们可以更加精准地控制缓存,即使是在 http 缓存过期之后也可以使用.因此 ...
- js便签笔记(10) - 分享:json2.js源码解读笔记
1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...
- js便签笔记(10) - 分享:json.js源码解读笔记
1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...
- vue.js源码学习分享(一)
今天看了vue.js源码 发现非常不错,想一边看一遍写博客和大家分享 /** * Convert a value to a string that is actually rendered. *转换 ...
- BAT资深工程师 由浅入深分析 Tp5&Tp6底层源码 - 分享
BAT资深工程师由浅入深分析Tp5&Tp6底层源码 第1章 课程简介 本章主要让大家知道本套课程的主线, 导学内容,如何学习源码等,看完本章要让小伙伴觉得这个是必须要掌握的,并且对加薪有很大的 ...
- events.js 源码分析
events.js 源码分析 1. 初始化 // 使用 this.ee = new EventEmitter(); // 源码 // 绑定this域,初始化 _events,_eventsCount和 ...
随机推荐
- Gradle在大型Java项目上的应用
在Java构建工具的世界里,先有了Ant,然后有了Maven.Maven的CoC[1].依赖管理以及项目构建规则重用性等特点,让Maven几乎成为Java构建工具的事实标准.然而,冗余的依赖管理配置. ...
- Codeforces Round #205 (Div. 2) : A
题意: 要求找到最少次数的交换次数使得两组数都是偶数: 很明显答案要么是0,要么是1,或者不管怎么交换都不行(-1): 所以: #include<cstdio> #define maxn ...
- hOAuth2.0认证和授权原理
原文地址: http://www.6zou.net/tech/what_is_oauth.html http://www.phpddt.com/%E4%BA%8C%E6%AC%A1%E5%BC%80% ...
- Quartz 有状态的JobDataMap
Quartz,每次执行job,job永远是全新的对象,但是,如果job实现org.quartz.StatefulJob接口,而不是job接口. 此时JobDetail的JobDataMap将会共享一个 ...
- 【HDOJ】1811 Rank of Tetris
并查集+拓扑排序.使用并查集解决a = b的情况. #include <iostream> #include <cstdio> #include <cstring> ...
- 悟透Javascript undefined,null,"",0这四个值转换为逻辑值时就是false &this关键字
话题一:undefined,null,"",0这四个值转换为逻辑值时就是false 也就是在if判断时会把上面的五个作为false来判断.但是它们的类型确是不尽相同的,如下所示. ...
- bzoj2326
首先不难得出递推式f[i]=(f[i-1]*10^k+i) mod m;f[i]表示接到第i个数时的余数,k表示i的位数不难想到先按位数穷举位数,然后对于确定的位数,构造矩阵解决易得出:f[i] ...
- (转载)mysql中limit用法
(转载)http://hi.baidu.com/sppeivan/item/e45179375d6778c62f8ec221 mysql中limit用法 使用查询语句的时候,经常要返回前几条或者中 ...
- HTMLTestRunner生成空白resault.html
发现一奇葩问题,用idle或pyscripter执行脚本,生成的是空白html,通过cmd,进入脚本目录执行python xx.py,却能生成测试报告. HTMLTestRunner 例子 #codi ...
- BZOJ1057 [ZJOI2007]棋盘制作(极大化思想)
1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec Memory Limit: 162 MB Submit: 1848 Solved: 936 [Submit][Sta ...