之前公司做了一个分析云平台,用来跟踪收集海量的用户行为的相关数据,供运营人员实时监控网站访问量,统计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源码分享的更多相关文章

  1. vue源码分析—Vue.js 源码构建

    Vue.js 源码是基于 Rollup 构建的,它的构建相关配置都在 scripts 目录下.(Rollup 中文网和英文网) 构建脚本 通常一个基于 NPM 托管的项目都会有一个 package.j ...

  2. vue源码分析—Vue.js 源码目录设计

    Vue.js 的源码都在 src 目录下,其目录结构如下 src ├── compiler # 编译相关 ├── core # 核心代码 ├── platforms # 不同平台的支持 ├── ser ...

  3. “限时分享“ 本地80个小游戏 HTML+CSS+JS源码分享

    ​ 里面有80款小游戏源码,支持内置导航,可以拿来练手或者消磨时间,具体功能以及游戏请看下图 ​ ​ ​ ​ ​ ​ ​ ​ 维京战争小游戏源码 链接:https://pan.baidu.com/s/ ...

  4. basket.js 源码分析

    basket.js 源码分析 一.前言 basket.js 可以用来加载js脚本并且保存到 LocalStorage 上,使我们可以更加精准地控制缓存,即使是在 http 缓存过期之后也可以使用.因此 ...

  5. js便签笔记(10) - 分享:json2.js源码解读笔记

    1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...

  6. js便签笔记(10) - 分享:json.js源码解读笔记

    1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...

  7. vue.js源码学习分享(一)

    今天看了vue.js源码  发现非常不错,想一边看一遍写博客和大家分享 /** * Convert a value to a string that is actually rendered. *转换 ...

  8. BAT资深工程师 由浅入深分析 Tp5&Tp6底层源码 - 分享

    BAT资深工程师由浅入深分析Tp5&Tp6底层源码 第1章 课程简介 本章主要让大家知道本套课程的主线, 导学内容,如何学习源码等,看完本章要让小伙伴觉得这个是必须要掌握的,并且对加薪有很大的 ...

  9. events.js 源码分析

    events.js 源码分析 1. 初始化 // 使用 this.ee = new EventEmitter(); // 源码 // 绑定this域,初始化 _events,_eventsCount和 ...

随机推荐

  1. Gradle在大型Java项目上的应用

    在Java构建工具的世界里,先有了Ant,然后有了Maven.Maven的CoC[1].依赖管理以及项目构建规则重用性等特点,让Maven几乎成为Java构建工具的事实标准.然而,冗余的依赖管理配置. ...

  2. Codeforces Round #205 (Div. 2) : A

    题意: 要求找到最少次数的交换次数使得两组数都是偶数: 很明显答案要么是0,要么是1,或者不管怎么交换都不行(-1): 所以: #include<cstdio> #define maxn ...

  3. hOAuth2.0认证和授权原理

    原文地址: http://www.6zou.net/tech/what_is_oauth.html http://www.phpddt.com/%E4%BA%8C%E6%AC%A1%E5%BC%80% ...

  4. Quartz 有状态的JobDataMap

    Quartz,每次执行job,job永远是全新的对象,但是,如果job实现org.quartz.StatefulJob接口,而不是job接口. 此时JobDetail的JobDataMap将会共享一个 ...

  5. 【HDOJ】1811 Rank of Tetris

    并查集+拓扑排序.使用并查集解决a = b的情况. #include <iostream> #include <cstdio> #include <cstring> ...

  6. 悟透Javascript undefined,null,"",0这四个值转换为逻辑值时就是false &this关键字

    话题一:undefined,null,"",0这四个值转换为逻辑值时就是false 也就是在if判断时会把上面的五个作为false来判断.但是它们的类型确是不尽相同的,如下所示. ...

  7. bzoj2326

    首先不难得出递推式f[i]=(f[i-1]*10^k+i) mod m;f[i]表示接到第i个数时的余数,k表示i的位数不难想到先按位数穷举位数,然后对于确定的位数,构造矩阵解决易得出:f[i]   ...

  8. (转载)mysql中limit用法

    (转载)http://hi.baidu.com/sppeivan/item/e45179375d6778c62f8ec221   mysql中limit用法 使用查询语句的时候,经常要返回前几条或者中 ...

  9. HTMLTestRunner生成空白resault.html

    发现一奇葩问题,用idle或pyscripter执行脚本,生成的是空白html,通过cmd,进入脚本目录执行python xx.py,却能生成测试报告. HTMLTestRunner 例子 #codi ...

  10. BZOJ1057 [ZJOI2007]棋盘制作(极大化思想)

    1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 1848  Solved: 936 [Submit][Sta ...