2

页面生命周期抽象为三个动作: 「进入」、「活跃状态切换」、「离开」

动作触发行为
进入首次加载、页面跳转、刷新、浏览器前进后退
活跃状态切换页面失去焦点/获得焦点、切换窗口最小化、切换浏览器Tab、电脑睡眠和唤醒
离开关闭窗口、页面跳转、刷新、浏览器前进后退

计算页面停留时长既如何监控这三个动作,然后在对应触发的事件中记录时间戳,比如要统计活跃停留时长就把 active 区间相加即可,要统计总时长既 tn -t0 。
停留时长

监听路由变化
目前主流的单页应用大部分都是基于 browserHistory (history api) 或者 hashHistory 来做路由处理,我们可以通过监听路由变化来判断页面是否有可能切换。注意是有可能切换,因为URL发生变化不代表页面一定切换,具体的路由配置是由业务决定的(既URL和页面的匹配规则)。
browserHistory
路由的变化本质都会调用 History.pushState() 或 History.replaceState() ,能监听到这两个事件就能知道。通过 popstate 事件能解决一半问题,因为 popstate 只会在浏览器前进后退的时候触发,当调用 history.pushState() or history.replaceState() 的时候并不会触发。
这里需要通过猴子补丁(Monkeypatch)解决,运行时重写 history.pushState 和 history.replaceState 方法:

let _wr =  function (type) {  
  let orig = window.history[type]
  return  function () {
    let rv = orig.apply(this, arguments)
    let e = new Event(type.toLowerCase())
    e.arguments = arguments
    window.dispatchEvent(e)
    return rv
  }
}
window.history.pushState = _wr('pushState')  
window.history.replaceState = _wr('replaceState')
window.addEventListener('pushstate',  function (event) {})  
window.addEventListener('replacestate',  function (event) {})

hashHistory 的实现是基于 hash 的变化,hash 的变化可以通过 hashchange 来监听
方案2: 数据分析平台定义

假设我们最终上报后有一个数据分析平台来展现,我们可以在类似数据平台来配置页面规则,这样在客户端实现的代码逻辑就不需要区分页面,而是每次URL发生变化就将数据上报,最终通过数据平台配置的页面URL规则来求和、过滤数据等。

当数据展现平台不支持配置URL规则来区分页面的时候,可以采用方案1;当有数据平台支持的时候采用方案2更合理;

2.1.3 对于页面进入和离开相关事件整理

首次加载关闭窗口刷新页面跳转浏览器前进后退
单页(browserHistory)loadbeforeunloadload/beforeunloadpushstate/replacestatepopstate
单页(hashHistory)loadbeforeunloadload/beforeunloadhashchangehashchange
多页loadbeforeunloadload/beforeunloadload/beforeloadpageshow/pagehide

如何监听页面活跃状态切换?
可以通过 Page Visibility API 以及在 window 上声明 onblur/onfocus 事件来处理。

2.2.1 Page Visibility API

一个网页的可见状态可以通过 Page Visibility API 获取,比如当用户 切换浏览器Tab、最小化窗口、电脑睡眠 的时候,系统API会派发一个当前页面可见状态变化的 visibilitychange 事件,然后在事件绑定函数中通过 document.hidden 或者 document.visibilityState 读取当前状态。

document.addEventListener('visibilitychange',  function (event) {  
  console.log(document.hidden, document.visibilityState)
})

2.2.2 onblur/onfocus

可以通过 Page Visibility API 以及在 window 上声明 onblur/onfocus 事件来处理。 对于PC端来说,除了监听上述相关事件外,还可以考虑监听鼠标行为,比如当一定时间内鼠标没有操作则认为用户处于非活跃状态。


_____
56 声望0 粉丝