以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: '', // 访问记录idname: to.name, // 访问页面名称标识startTime: new Date().getTime() // 本地访问页面的开始时间(时间戳)}))}}
},
mounted () {let userAgent = window.navigator.userAgentthis.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')) : nullif (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')) : nullif (recordPageDataChange && recordPageDataChange.viewId !== recordPageData.viewId) returnlocalStorage.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, // 访问记录idname: 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 hiddenlet visibilityChangeif (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, // 访问记录idname: 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')) : nullif (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')) : nulllet 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, // 访问记录idname: recordPageData.name, // 访问页面名称标识viewTime // 页面的访问时长(时间戳)}))}cb && cb()}).catch(() => {localStorage.setItem('recordPageData', JSON.stringify({viewId: recordPageData.viewId, // 访问记录idname: recordPageData.name, // 访问页面名称标识viewTime // 页面的访问时长(时间戳)}))cb && cb()})} else {cb && cb()}}
},
beforeRouteLeave (to, from, next) {let recordPageData = localStorage.getItem('recordPageData') ? JSON.parse(localStorage.getItem('recordPageData')) : nulllet 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, // 访问记录idname: recordPageData.name, // 访问页面名称标识viewTime // 页面的访问时长(时间戳)}))}next()}).catch(() => {localStorage.setItem('recordPageData', JSON.stringify({viewId: recordPageData.viewId, // 访问记录idname: recordPageData.name, // 访问页面名称标识viewTime // 页面的访问时长(时间戳)}))next()})} else {next()}}

说明:hyperlinkJump 方法是在超链接跳转前调用的,安卓能检测得到超链接跳转,但IOS不能,故做此兼容

JS统计页面访问时长相关推荐

  1. js统计页面停留时长

    前言 页面停留时间简称为Tp 是网站分析中的一个指标 用于反映用户在某些页面的停留时间的长短 我们可以把页面的生命周期分为三个动作 进入 活跃状态切换 离开 一.如何监听页面的进入和离开 对于常规页面 ...

  2. 如何精确统计页面停留时长

    关注公众号 前端开发博客,回复"加群" 加入我们一起学习,天天进步 作者:今日头条技术 链接:https://techblog.toutiao.com/2018/06/05/ru- ...

  3. Android 如何正确统计页面停留时长

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/112546517 本文出自[赵彦军的博客] 在Android中经常有统计页面停留时长 ...

  4. spark项目实战:电商分析平台之各个范围Session步长、访问时长占比统计(需求一)

    spark项目实战:电商分析平台之各个范围Session步长.访问时长占比统计(需求一) 项目基本信息,架构,需要一览 各个范围Session步长.访问时长占比统计概述 各个范围Session步长.访 ...

  5. php统计在线时长,js统计网站运行时长

    js统计网站运行时长 第一种: 网站 function siteTime(){ window.setTimeout("siteTime()", 1000); var seconds ...

  6. 如何知道页面浏览时长系列之 Web 篇

    一.前言 页面浏览时长是网站分析中很常见的一个指标,反映用户在某些页面上浏览时间的长短,体现了网站用户黏性.然而精确的页面浏览时长是很难统计的,比如需要考虑单页面网页应用路由切换.用户切换浏览器 ta ...

  7. 【实时数仓】DWS层的定位、DWS层之访客主题计算(PV、UV、跳出次数、计入页面数、连续访问时长)

    文章目录 一 DWS层与DWM层的设计 1 设计思路 2 需求梳理 3 DWS层定位 二 DWS层-访客主题计算 1 需求分析与思路 2 功能实现 (1)封装VisitorStatsApp,读取Kaf ...

  8. 介绍一个统计各个网站访问时长的Chrome扩展 - Rooster

    这个扩展的名称叫Rooster,公鸡. 安装之后,在Chrome上方的工具栏里会出现一只公鸡的图标: 此后新建一个标签页,会看到如下提示,表明该扩展已经在后台收集每个网站的访问时长了.

  9. 如何知道页面浏览时长?

    1. 前言 页面浏览时长是用于统计用户在页面的停留时长.对于神策分析 iOS SDK 而言,在没有推出页面浏览时长自动采集功能之前,客户是通过手动调用开始计时和结束计时的相关接口实现页面浏览时长采集的 ...

  10. 页面访问时发生错误 For input string fullname

    出错堆栈信息: <!DOCTYPEhtmlPUBLIC "-//W3C//DTD XHTML 1.0Transitional//EN""http://www.w3. ...

最新文章

  1. Linux串口原理与编程
  2. simple c语言,C语言——指针(simple).ppt
  3. GridView 实现LinkButton下载文件/附件
  4. Android之一起制作简易唱片播放器
  5. 已解决:Connecting to raw.githubusercontent.com |185.199.109.133|:443... Unable to establish SSL connect
  6. 【ABP框架系列学习】模块系统(4)
  7. 什么是微调(Fine Tune)?什么时候使用什么样的微调?【数据量和数据相似度决定】
  8. C语言 提取字符串中的所有整数
  9. Java进阶:SpringMVC中获取web.xml中的全局参数
  10. 对文式编程的一些误解
  11. centos7 redis分布式集群问题总结
  12. 【风马一族_Java】如何使用ACSLL表的值,
  13. Google Breakpad的使用
  14. Kafka Simple Consumer
  15. 树莓派安装qq linux,在树莓派上安装Ubuntu Core
  16. linux免费商用字体,免费可商用字体~文泉驿正黑体
  17. Denoise-----去除噪声
  18. IP代理池Proxy_Pool使用教程(Windows版)
  19. 第十次ccf 分蛋糕
  20. 为效率而生-开源Mac版Google Authenticator认证客户端GoldenPasspor

热门文章

  1. 能量原理与变分法笔记06:高阶导数的变分问题(包含函数的高阶导数)
  2. mysql not null 语法_[MySQL]--MySQL表中某个列插入数据总被截断,报编码方式的语法错误,实际是column的not null属性和更改编码语法导致的冲突。...
  3. 从bilibili下载视频,取其音频
  4. 导入tkinter出错
  5. android 辅助功能(无障碍) AccessibilityService 实战入门详解
  6. redission限流RedisException问题排查
  7. 计算机发邮件试题,计算机考试题库:计算机网络模拟练习题(4)
  8. Activiti in Action(实战Activiti)-目录
  9. 行业案例 | AR+工业互联网,智慧园区的全新服务模式
  10. 《Loy解说Eureka服务端源码(一)》