JS統計頁面訪問時長

以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不能,故做此兼容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章