UNPKG

x-track

Version:
161 lines (141 loc) 4.97 kB
/* * @description 页面埋点统计(停留时间) * * 当浏览器进入页面时,触发onload * 当关闭浏览器时,执行顺序 onbeforeunload--> visibilitychange --> onunload * 每一次进入页面 entry_time 记当前时间戳,初始化时记一次当前时间戳 * 每一次隐藏页面 hidden_time 记当前时间戳, onbeforeunload时再记一次当前时间戳 * hidden_time[i] - entry_time[i] 位每次停留的时间,求和为总的停留时间。 * * * 关闭窗口请求参考链接:https://usefulangle.com/post/62/javascript-send-data-to-server-on-page-exit-reload-redirect * * 1. 可用ajax 同步请求,但是对用户不友好 * 2. 可用ajax 异步请求,后端可能需要配置 ignore_user_abort * 3. 可用 navigator.sendBeacon,不兼容ie。(推荐这个) * * trackCb 接收的数据 * { * split_time, // 页面停留时间 [1400, 1200, 1000] * stay_time, // 页面总的停留时间 3600 * * } * * @example * new PageView({trackCb: fn}) */ function PageView(option) { // 计算页面显示时的时间戳 this.entry_time = []; // 计算页面隐藏时的时间戳 this.hidden_time = []; // 停留时间 总的停留时间 = 停留时间累加 this.split_time = []; // 总的停留时间 this.stay_time = 0; // 是否触发过Pageview 埋点 (连续点击a链接跳转,beforeunload 会触发多次) this.bTracked = false; this.trackCb = option && option.trackCb ? option.trackCb : null, // 初始化 this.init(); } // 页面 进入 PageView.prototype.countEntryTime = function () { this.entry_time.push(new Date().getTime()); }; // 页面 隐藏 PageView.prototype.countHiddenTime = function () { this.hidden_time.push(new Date().getTime()); }; // 组装数据 PageView.prototype.getAnalysisData = function () { let aEntryTime = this.entry_time, aHiddenTime = this.hidden_time; // 计算停留时间 for (let i = 0; i < aEntryTime.length; i++) { let t = +((aHiddenTime[i] - aEntryTime[i])).toFixed() this.split_time.push(t); } // 计算停留总时长 let nStayTime = 0; for (let i = 0; i < this.split_time.length; i++) { nStayTime += this.split_time[i]; }; nStayTime = +nStayTime.toFixed(); this.stay_time = nStayTime; return { split_time: this.split_time, stay_time: this.stay_time } }; // 关闭或刷新页面数据处理 回调页面逻辑 PageView.prototype.setAnalysis = function () { let data = this.getAnalysisData(); if (data.stay_time) { this.trackCb && this.trackCb(data); } else { console.error('停留时间计算错误'); } }; // 关闭或刷新页面 PageView.prototype.initCloseWindow = function () { let self = this; // onbeforeunload onunload https://stackoverflow.com/questions/6895564/difference-between-onbeforeunload-and-onunload this.addEventListener(window, 'beforeunload', function (event) { if (self.bTracked === false) { self.bTracked = true; // 关闭或刷新时 记一次hidden时间 self.countHiddenTime(); self.setAnalysis(); } }, false); }; /** * @description 页面 显示隐藏 * 参考: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API */ PageView.prototype.initChangeVisible = function () { let self = this; function handleVisibilityChange() { // 页面隐藏计算时间 if (document[hidden]) { self.countHiddenTime(); } else { // 页面显示统计时间 self.countEntryTime(); } } // 设置隐藏属性和改变可见属性的事件的名称 var hidden, visibilityChange; if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support hidden = "hidden"; visibilityChange = "visibilitychange"; } else if (typeof document.msHidden !== "undefined") { hidden = "msHidden"; visibilityChange = "msvisibilitychange"; } else if (typeof document.webkitHidden !== "undefined") { hidden = "webkitHidden"; visibilityChange = "webkitvisibilitychange"; } // 兼容 addEventListener this.addEventListener(document, visibilityChange, handleVisibilityChange, false); }; // 监听事件 兼容性 PageView.prototype.addEventListener = function (ele, event, fn, bubble) { if (ele.addEventListener) { ele.addEventListener(event, fn, bubble); } else { ele.attachEvent('on' + event, fn); } }; PageView.prototype.init = function () { // 第一次进入页面时 记entry时间 this.countEntryTime(); // 初始化 页面隐藏时间 this.initChangeVisible(); // 初始化 页面关闭或刷新事件 this.initCloseWindow(); }; export { PageView };