1、在路由的meta属性中,给需要记录访问时长的页面添加hasViewTime属性,以便全局处理页面,代码如下:
{
path: '路由地址',
name: '页面模块名称',
component: '页面模块',
meta: {
hasViewTime: true/false
}
}
2、在页面主入口文件App.vue文件中,记录访问页面的初始数据,同时初始化页面隐藏/关闭时监听事件,代码如下:
data () {
return {
systemEnv: '' // 移动设备类型
}
},
watch: {
$route (to, from) {
// 进入页面时,记录当前访问页面的浏览数据
if (to.meta.hasViewTime) {
localStorage.setItem('recordPageData', JSON.stringify({
viewId: '', // 访问记录id
name: to.name, // 访问页面名称标识
startTime: new Date().getTime() // 本地访问页面的开始时间(时间戳)
}))
}
}
},
mounted () {
let userAgent = window.navigator.userAgent
this.systemEnv = (userAgent.indexOf('iPhone') > -1 || userAgent.indexOf('iPad') > -1) ? 'iPhone' : 'Android'
// 页面访问时长统计
this.viewPageTimeFun()
},
methods: {
addViewTime () {
// 具体的记录页面访问时长的接口,就不附代码了
},
// 页面访问时长统计
viewPageTimeFun () {
// ******下次进入页面时,判断条件,发送请求,记录页面浏览数据******
let recordPageData = localStorage.getItem('recordPageData') ? JSON.parse(localStorage.getItem('recordPageData')) : null
if (recordPageData && recordPageData.viewId && recordPageData.viewTime) {
// 发送请求
this.addViewTime({
VIEW_ID: recordPageData.viewId,
VIEW_DURATION: recordPageData.viewTime
}).then(res => {
if (res.status === 'success') {
let recordPageDataChange = localStorage.getItem('recordPageData') ? JSON.parse(localStorage.getItem('recordPageData')) : null
if (recordPageDataChange && recordPageDataChange.viewId !== recordPageData.viewId) return
localStorage.removeItem('recordPageData')
}
})
}
// ******下次进入页面时,判断条件,发送请求,记录页面浏览数据******
// ******对页面的不可视状态(如:关闭、隐藏等)进行监听******
// 为IOS设备监听做兼容
if (this.systemEnv === 'iPhone') {
window.addEventListener('pagehide', () => {
let recordPageData = localStorage.getItem('recordPageData') ? JSON.parse(localStorage.getItem('recordPageData')) : null
// 判断是否存在需要处理的页面
if (recordPageData && recordPageData.viewId) {
let startTime = recordPageData.startTime // 本地访问页面的开始时间(时间戳)
let endTime = new Date().getTime() // 本地访问页面的结束时间(时间戳)
let viewTime = endTime - startTime // 页面的访问时长(时间戳)
localStorage.setItem('recordPageData', JSON.stringify({
viewId: recordPageData.viewId, // 访问记录id
name: recordPageData.name, // 访问页面名称标识
viewTime // 页面的访问时长(时间戳)
}))
if (this.addViewTime) {
this.addViewTime({
VIEW_ID: recordPageData.viewId,
VIEW_DURATION: viewTime
}).then(res => {
if (res.status === 'success') {
localStorage.removeItem('recordPageData')
}
})
}
}
})
}
// 通用监听
let hidden
let visibilityChange
if (typeof document.hidden !== 'undefined') {
hidden = 'hidden'
visibilityChange = 'visibilitychange'
} else if (typeof document.msHidden !== 'undefined') {
hidden = 'msHidden'
visibilityChange = 'msvisibilitychange'
} else if (typeof document.webkitHidden !== 'undefined') {
hidden = 'webkitHidden'
visibilityChange = 'webkitvisibilitychange'
}
document.addEventListener(visibilityChange, () => {
let recordPageData = localStorage.getItem('recordPageData') ? JSON.parse(localStorage.getItem('recordPageData')) : null
// 判断是否存在需要处理的页面
if (recordPageData && recordPageData.viewId) {
if (document[hidden]) {
let startTime = recordPageData.startTime // 本地访问页面的开始时间(时间戳)
let endTime = new Date().getTime() // 本地访问页面的结束时间(时间戳)
let viewTime = endTime - startTime // 页面的访问时长(时间戳)
localStorage.setItem('recordPageData', JSON.stringify({
viewId: recordPageData.viewId, // 访问记录id
name: recordPageData.name, // 访问页面名称标识
viewTime // 页面的访问时长(时间戳)
}))
if (this.addViewTime) {
this.addViewTime({
VIEW_ID: recordPageData.viewId,
VIEW_DURATION: viewTime
}).then(res => {
if (res.status === 'success') {
localStorage.removeItem('recordPageData')
}
})
}
}
}
}, false)
// ******对页面的不可视状态(如:关闭、隐藏等)进行监听******
}
}
以微信环境为例,这一部分的监听,主要是处理处理以下情况:
(1)点击微信左上角自带的关闭按钮;
(2)微信程序进入后台、或是通过手势滑动关闭微信程序;
(3)超链接跳转;不能监听的情况
(1)页面超链接跳转;设备差别说明和处理:
(1)安卓设备可通过visibilityChange监听以上情况;
(2)IOS设备通过visibilityChange监听以上情况,会时灵时不灵的,如果有效的话,以上情况都能监听;如若失效的话,以上情况皆不能监听(个人测试如此),故为IOS设备添加pagehide监听(这个能保证监听到点击微信左上角自带的关闭按钮)
(3)安卓设备的监听中能发送请求,IOS设备不能,故为兼容,做了下次进入发送请求的处理
监听方法说明详见:https://blog.csdn.net/mx_csdn/article/details/101674708
3、由于上面的监听无法监听到超链接跳转之类的页面离开,以及页面之间的路有跳转,故对具体的页面做处理,代码如下:
mounted () {
this.addViewRecor().then(data => {
let recordPageData = localStorage.getItem('recordPageData') ? JSON.parse(localStorage.getItem('recordPageData')) : null
if (data.data.data && data.data.data.VIEW_ID && recordPageData) {
recordPageData.viewId = data.data.data.VIEW_ID // 访问记录id
// 缓存记录
localStorage.setItem('recordPageData', JSON.stringify(recordPageData))
}
})
},
methods: {
addViewRecord () {
// 具体的请求,为页面生成一条访问记录,并返回记录id(),就不附代码了
},
addViewTime () {
// 具体的记录页面访问时长的接口,就不附代码了
},
// 由于超链接跳转时,ios设备无法检测到,故对超链接跳转时,对页面浏览时长做单独处理
hyperlinkJump (cb) {
let recordPageData = localStorage.getItem('recordPageData') ? JSON.parse(localStorage.getItem('recordPageData')) : null
let startTime = recordPageData.startTime // 本地访问页面的开始时间(时间戳)
let endTime = new Date().getTime() // 本地访问页面的结束时间(时间戳)
let viewTime = endTime - startTime // 页面的访问时长(时间戳)
// 判断是否为微信环境,并发送请求
if (recordPageData.viewId) {
this.addViewTime({
VIEW_ID: recordPageData.viewId,
VIEW_DURATION: viewTime
}).then(res => {
if (res.status === 'success') {
localStorage.removeItem('recordPageData')
} else {
localStorage.setItem('recordPageData', JSON.stringify({
viewId: recordPageData.viewId, // 访问记录id
name: recordPageData.name, // 访问页面名称标识
viewTime // 页面的访问时长(时间戳)
}))
}
cb && cb()
}).catch(() => {
localStorage.setItem('recordPageData', JSON.stringify({
viewId: recordPageData.viewId, // 访问记录id
name: recordPageData.name, // 访问页面名称标识
viewTime // 页面的访问时长(时间戳)
}))
cb && cb()
})
} else {
cb && cb()
}
}
},
beforeRouteLeave (to, from, next) {
let recordPageData = localStorage.getItem('recordPageData') ? JSON.parse(localStorage.getItem('recordPageData')) : null
let startTime = recordPageData.startTime // 本地访问页面的开始时间(时间戳)
let endTime = new Date().getTime() // 本地访问页面的结束时间(时间戳)
let viewTime = endTime - startTime // 页面的访问时长(时间戳)
// 发送请求
if (recordPageData.viewId) {
this.addViewTime({
VIEW_ID: recordPageData.viewId,
VIEW_DURATION: viewTime
}).then(res => {
if (res.status === 'success') {
localStorage.removeItem('recordPageData')
} else {
localStorage.setItem('recordPageData', JSON.stringify({
viewId: recordPageData.viewId, // 访问记录id
name: recordPageData.name, // 访问页面名称标识
viewTime // 页面的访问时长(时间戳)
}))
}
next()
}).catch(() => {
localStorage.setItem('recordPageData', JSON.stringify({
viewId: recordPageData.viewId, // 访问记录id
name: recordPageData.name, // 访问页面名称标识
viewTime // 页面的访问时长(时间戳)
}))
next()
})
} else {
next()
}
}
说明:hyperlinkJump 方法是在超链接跳转前调用的,安卓能检测得到超链接跳转,但IOS不能,故做此兼容