以vue單頁面項目爲例
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不能,故做此兼容