背景
用户对网页的浏览时长可以判断出当前网页对用户的需求程度,以及当前网页的优先级和重要性。
如果用户在一个网页中停留时长较短的话则可以考虑精简这个网页,如果停留时间较长则可以考虑是否可以对这个网页进一步优化。
应用
- 多页面应用
- 单页面应用
如何获取?
多页面应用
在多页面应用中要获取用户的停留时间,需要用到下面几个API
- onload (页面加载完)
- onbeforeunload (页面关闭前)
- onpageshow (页面展示时)
- onpagehide (页面隐藏时)
Tips:
- 无论在页面关闭的时候(点击窗口关闭按钮),还是页面隐藏的时候(点击前进/后端按钮)都会触发
onpagehide
- 无论在首次加载还是刷新的时候,都会触发
onpageshow
,但是刷新的时候会先触发onpagehide
,再触发onpageshow
,其他两个API也是类似
这里选择使用 onpageshow
和 onpagehide
来实现这个功能,只需要在 onpageshow
设置初始时间值,在 onpagehide
获取最终时间值后求出差值,这个差值就是用户停留在页面中的时长。
let stayTime
window.onpageshow = ()=>{
stayTime = new Date().getTime()
}
window.onpagehide = ()=>{
stayTime = new Date().getTime() - stayTime
let record = localStorage.getItem('data')
let data = record && JSON.parse(record) || []
localStorage.setItem('data',JSON.stringify([...data,{user:new Date().getTime(),path:window.location.href,stayTime}]))
}
这里就将这个差值存储到了 localStorage 中,在项目中可以将这个值传给后台,后台再根据这个数据进行一些分析。
单页面应用
单页面应用的路由跳转,但是基于 H5的 History API(browserHistory)
和 Hash(hashHistory)
实现的。
browserHistory
单页面的browserHistory
路由是基于H5的History API实现的,我们只要监听popstate
就可以知道,点击前进后退按钮后url发生变化,这样就能计算出用户在该页面待了多长时间:
let timeStr
window.addEventListener('onload',(e)=>{
timeStr = new Date().getTime()
})
window.addEventListener('popstate',()=>{
let t = new Date().getTime() - timeStr
timeStr = new Date().getTime()
console.log('待了时长:'+ t)
})
但是,pushState
和replaceState
不会触发popstate,
(也就是点击router-view,$router.push,$router.replace,window.history.pushState,window.history.replaceState不会触发,可以自行试试)
那我们就统计不了用户待在该页面的时长的了;可是解决方法还是有的,只需要重写pushState
和replaceState
,然后监听两个自定义事件就行
// 对原函数做一个拓展
let rewriteHis = function(type){
let origin = window.history[type] // 先将原函数存放起来
return function(){ // 当window.history[type]函数被执行时,这个函数就会被执行
let rs = origin.apply(this, arguments) // 执行原函数
let e = new Event(type.toLocaleLowerCase()) // 定义一个自定义事假
e.arguments = arguments // 把默认参数,绑定到自定义事件上,new Event返回的结果,自身上市没有arguments的
window.dispatchEvent(e) // 触发自定义事件,把载荷传给自定义事件
return rs
}
}
window.history.pushState = rewriteHis('pushState') // 覆盖原来的pushState方法
window.history.replaceState = rewriteHis('replaceState') // 覆盖原来的replaceState方法
// 监听自定义事件, pushstate事件是在rewriteHis时注册的,不是原生事件
// 当点击router-link 或者 window.history.pushState 或者 this.$router.push 时都会被该事件监听到
window.addEventListener('pushstate',()=>{})
// 监听自定义事件, replacestate事件是在rewriteHis时注册的,不是原生事件
// 当点击window.history.replaceState 或者 this.$router.replace 时都会被该事件监听到
window.addEventListener('replacestate',()=>{})
browserHistory路由变化监听完整代码
let timeStr
let rewriteHis = function(type){
let origin = window.history[type]
return function(){
let rs = origin.apply(this, arguments)
let e = new Event(type.toLocaleLowerCase())
e.arguments = arguments
window.dispatchEvent(e)
return rs
}
}
window.history.pushState = rewriteHis('pushState')
window.history.replaceState = rewriteHis('replaceState')
window.addEventListener('onload',(e)=>{
timeStr = new Date().getTime()
})
window.addEventListener('popstate',()=>{
let t = new Date().getTime() - timeStr
timeStr = new Date().getTime()
console.log('待了时长popstate:'+ t)
})
window.addEventListener('pushstate',()=>{
let t = new Date().getTime() - timeStr
timeStr = new Date().getTime()
console.log('待了时长pushstate:'+ t)
})
window.addEventListener('replacestate',()=>{
let t = new Date().getTime() - timeStr
timeStr = new Date().getTime()
console.log('待了时长replacestate:'+ t)
})
hashHistory
hashHistory
就相对简单,可以直接监听 hashchange
即可
window.addEventListener('hashchange',()=>{
let t = new Date().getTime() - timeStr
timeStr = new Date().getTime()
console.log('待了时长:'+ t)
})