9 changed files with 242 additions and 24 deletions
@ -0,0 +1,110 @@ |
|||
var uaParser = require('ua-parser-js') |
|||
//https://afantasy.ninja/2017/05/08/user-tracking-iii/
|
|||
// 用户停留时间
|
|||
// addEvent() 是包装了 `window.addEventListener` 和 `window.attachEvent` 的事件监听函数
|
|||
var r = window.requestAnimationFrame |
|||
var c = window.cancelAnimationFrame |
|||
var h |
|||
var lt = 0 |
|||
var ltStart |
|||
var inActiveTime |
|||
var inActiveThreshold = 60 * 60 * 100 |
|||
// 创建一个心跳闭包,负责向 lifetime 增加累计时间
|
|||
var h = (function() { |
|||
var timer |
|||
|
|||
function beat() { |
|||
var now = new Date() |
|||
var diff = now - ltStart |
|||
lt = lt + diff |
|||
inActiveTime = inActiveTime + diff |
|||
ltStart = now |
|||
if (inActiveTime <= inActiveThreshold) { |
|||
timer = r(beat) |
|||
} else { |
|||
timer = null |
|||
} |
|||
document.getElementById('inActiveTime').innerText = inActiveTime |
|||
} |
|||
|
|||
return { |
|||
start: function() { |
|||
if (!timer) { |
|||
ltStart = new Date() |
|||
timer = r(beat) |
|||
} |
|||
}, |
|||
stop: function() { |
|||
if (timer) { |
|||
c(timer) |
|||
timer = null |
|||
} |
|||
} |
|||
} |
|||
})() |
|||
|
|||
function onFocus() { |
|||
h.start() |
|||
} |
|||
|
|||
function onBlur() { |
|||
h.stop() |
|||
} |
|||
|
|||
// 在 PC 端使用 focusin / focusout / focus / blur 事件
|
|||
if ('onfocusin' in document) { |
|||
document.onfocusin = onFocus |
|||
document.onfocusout = onBlur |
|||
} else { |
|||
window.onfocus = onFocus |
|||
window.onblur = onBlur |
|||
} |
|||
// 在移动端使用 Page Visibility API 检查页面是否 active
|
|||
var prefixes = ['', 'webkit', 'moz', 'ms', 'o'] |
|||
var pf |
|||
var hiddenKey |
|||
var eventKey |
|||
if (isMobile) { |
|||
for (var i = 0; i < prefixes.length; i++) { |
|||
pf = prefixes[i] |
|||
hiddenKey = pf ? (pf + 'Hidden') : 'hidden' |
|||
if (hiddenKey in document) { |
|||
eventKey = pf + 'visibilitychange' |
|||
break |
|||
} |
|||
} |
|||
if (eventKey) { |
|||
addEvent(document, eventKey, function() { |
|||
document[hiddenKey] ? onBlur() : onFocus() |
|||
}) |
|||
} |
|||
} |
|||
inActiveTime = 0 |
|||
h.start() // 开始计算 lifetime
|
|||
|
|||
function isMobile() { |
|||
const ua = uaParser(navigator.userAgent) |
|||
if (ua.device) { |
|||
let {type} = ua.device |
|||
if (type && type == 'mobile') { |
|||
return true |
|||
} |
|||
} |
|||
return false |
|||
} |
|||
|
|||
function addEvent(element, event, callback) { |
|||
if (element.addEventListener) { // 支持使用 addEventListener()
|
|||
if (event.slice(0, 2) === 'on') // 以 "on" 开头,不需要,则去掉
|
|||
event = event.slice(2) |
|||
element.addEventListener(event, callback) |
|||
} else if (element.attachEvent) { // 支持使用 attachEvent()
|
|||
if (event.slice(0, 2) !== 'on') // 没有以 "on" 开头,需要,则加上
|
|||
event = 'on' + event |
|||
element.attachEvent(event, callback) |
|||
} else { |
|||
event.slice(0, 2) !== 'on' ? element['on' + event] = callback : element[event] = callback |
|||
} |
|||
} |
|||
|
|||
|
Loading…
Reference in new issue