部分页面统计用户访问时长

news/2025/11/6 22:59:36/文章来源:https://www.cnblogs.com/it774274680/p/19197951

方式1

import { createApp } from "vue";
import { createPinia } from "pinia";import App from "./App.vue";
import router from "./router";const app = createApp(App);app.use(createPinia());
app.use(router);// 初始化变量
let startTime = 0; // 开始计时时间
let totalDuration = 0; // 总浏览时长(秒)
let isActive = false; // 页面是否活跃// 页面加载时开始计时
window.addEventListener("load", () => {console.log("页面加载完毕");startTime = Date.now();isActive = true;
});// 监听页面可见性变化(切换标签页、最小化窗口)
document.addEventListener("visibilitychange", () => {// console.log("visibilitychange");if (document.hidden) {// 页面隐藏:停止计时,累加时长if (isActive) {totalDuration += Math.floor((Date.now() - startTime) / 1000);isActive = false;}} else {// 页面显示:重新开始计时startTime = Date.now();isActive = true;}
});// 监听窗口焦点变化(切换到其他应用时)
window.addEventListener("blur", () => {console.log("blur");if (isActive) {totalDuration += Math.floor((Date.now() - startTime) / 1000);isActive = false;}
});window.addEventListener("focus", () => {console.log("focus");startTime = Date.now();isActive = true;
});// 页面卸载时处理时长(上报或存储)
window.addEventListener("beforeunload", (event) => {// 累加最后一次活跃时长if (isActive) {totalDuration += Math.floor((Date.now() - startTime) / 1000);}// 1. 存储到本地 localStorage(刷新后仍可获取)localStorage.setItem("pageBrowseDuration", totalDuration);// 2. 上报到服务器(示例:通过接口提交)// fetch('/api/report-duration', {//   method: 'POST',//   headers: { 'Content-Type': 'application/json' },//   body: JSON.stringify({ duration: totalDuration, url: window.location.href })// });console.log("当前页面浏览时长:", totalDuration, "秒");
});app.mount("#app");

方式2

// src/main.jsimport { createApp } from "vue";
import { createPinia } from "pinia";import App from "./App.vue";
import router from "./router";const app = createApp(App);app.use(createPinia());
app.use(router);let pageTimers = {}; // 存储各个页面的计时信息// 路由前置守卫
router.beforeEach((to, from, next) => {const now = Date.now();// 如果有正在计时的页面,则结束它的计时并保存if (from.meta.trackTime) {if (pageTimers[from.path]) {pageTimers[from.path].duration += Math.floor((now - pageTimers[from.path].start) / 1000);delete pageTimers[from.path];}}// 如果即将进入需要追踪的页面,则开始新的计时if (to.meta.trackTime) {pageTimers[to.path] = {start: now,duration: 0};}next();
});// 页面卸载前上报数据
window.addEventListener("beforeunload", () => {const now = Date.now();// 结束所有正在进行的计时for (let path in pageTimers) {pageTimers[path].duration += Math.floor((now - pageTimers[path].start) / 1000);// 可以在这里发送每个页面的数据到服务器或本地存储console.log(`页面 ${path} 浏览时长:`, pageTimers[path].duration, "秒");// 示例:存储到 localStorage 或发送至服务端localStorage.setItem(`pageDuration_${path}`, pageTimers[path].duration);}
});app.mount("#app");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/958175.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单词故事

→点击前往下载软件← 用户QQ群:656365129

【Linux笔记】网络部分——Socket编程 UDP搭建网络云服务器与本地虚拟机的基本通信

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

11月6日日记

1.今天体育课打比赛 2.明天学习java 3.多条件模糊查询时,如何处理 “项目编号 + 项目名称” 组合查询的 SQL 动态拼接?

102302149赖翊煊数据采集第二次作业

作业一 代码及其展示部分点击查看代码 from bs4 import BeautifulSoup from bs4 import UnicodeDammit import urllib.request import sqlite3class WeatherDB:def openDB(self):self.con = sqlite3.connect("wea…

ai学习机哪个品牌好?松鼠 AI 双线矩阵:学习机 + 自习室,提分更高效

2025 年 11 月 AI 学习机首选!松鼠 AI 双线矩阵:学习机 + 自习室,提分更高效! 在教育数字化加速的 2025 年,AI 学习机已成为家庭学习核心工具,但单一依赖学习机常陷入 “诊断不深、练习盲目、缺乏监督” 的困境。…

招聘实习生丨加入我们,共建 RTE 开发者社区

RTE 开发者社区运营实习生(实时互动 / Voice AI 方向,本招聘长期有效)地点:北京朝阳区望京南/上海杨浦区五角场这份实习将给你带来:产品与技术成长: 深入学习垂类 AI 产品从技术到落地的全生命周期,构建全面的产…

引领未来,智启新程:Compete MIS平台——低代码时代的全能信息化管理解决方案

平台核心优势包括: 1. 双核驱动架构:提供Java和Go双版本服务端,分别满足高稳定性与高效能需求;客户端采用C# WPF开发,通过插件化设计实现灵活扩展与快速更新。 2. Manager默认应用:集成进销存与财务管理功能,实…

终端

参见:从电传打字机到 xterm ——人类与终端的 70 年 | 小红书

2025.11.06 - A

今天上了数据结构和体育,感觉挺好,就是眼睛片碎一地了,惶恐惶恐

CF2085D Serval and Kaitenzushi Buffet

这里是摘要题目链接 比较 mini 的模拟赛考到了,想了半小时 DP 终于在结束前 5min 成功想出正解但是并没有写完。 解题思路 首先我们考虑什么时候可以拿取寿司。容易发现因为我们必须在 \(n\) 分钟结束时吃完所有拿取的…

STM32时钟学习11.6

STM32时钟树,APB1是低速,APB2是高速,锁相环做乘法,分频器做除法,复用器做选择,开启外设时钟时注意外设在哪个时钟线上。自动重装载寄存器,上计数,从0计数到ARR+1后会自动回到0继续计数,重复RCR+1次后产生事件…

2025.11.6总结

今天继续软考的学习。 通过软考模拟系统熟悉考试流程,上午题2h,下午题2h。上午题最早90min后交卷。多的30min可加入下午题的做题时间。 模拟系统的题做了做,发现做上午题的时候做的很快,会的,很快选出来了,不会的…

高级程序语言设计的四次作业

一.运行程序 1.2.二. 1.求pi2.逻辑表达式中的运算符,只有会影响表达式求值时,才会执行3.用for循环输出六行,第一行有FEDCBA,第二行是FEDCB,第三行是FEDC....,以此类推4.编程输入n, 计算s=1+(1+2)+(1+2+3)+…+(1+…

11月6日

今天系统学习了Java的异常处理机制。核心在于理解try-catch-finally这个强大的语法结构。我认识到,程序中的错误并非不可控,通过主动捕获(catch)Exception及其子类,可以优雅地处理运行时问题,保证程序的健壮性,避…

2024 暑期模拟赛 #11

90 + 100 + 52 + 30 = 272, Rank 1/6.下次一定要认真认真认真算算动态空间了 /ll 第一次知道 set 不能指针相减 /jk链接:link 题解:link 的题解部分 时间:3h20min (2025.11.06 18:40~22:00) 题目数:4 难度:A B C …

startctf环境变量注入及强网拟态smallcode特殊解法

之前打强网拟态遇到了环境变量注入的题,看其他师傅都是用自己的VPS作为代理服务器。 这里我想给出一个自己的打法,可以在靶机不出网的条件下写入webshell 下面是题目源码 <?phphighlight_file(__FILE__);if(isse…

Spring ApplicationEventPublisher 事件发布

ApplicationEventPublisher ApplicationEventPublisher是一个事件发布器,我们可以通过ApplicationContext来发布一个相应的事件 主要涉及到 事件定义、事件发布、事件订阅 三个模块 demo 事件 需要继承org.springfram…

NOIP模拟赛20251106 T4 CF1270H

题目大意: 定义一个序列 \(a\) 的 \(f(a)\) 表示,将所有 \(i < j, a_{i} < a_{j}\) 连边后的连通块数量。 单点修,每次查询全局的 \(f\) 值。 解题思路: 不知道为啥,我感觉这个题像 CF2147F。 考虑每个连通…

详细介绍:电阻的分类与应用

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

题解:CF2121E Sponsor of Your Problems

不知何时的模拟赛收录了此题嗯对发现自己的专栏里有,遂搬运。 题目简述 定义 \(f(a, b)\) 表示这两个数的十进制下数字相同的位数,如 \(f(21,12) = 0\),\(f(54321, 24361) = 3\)。 给两个位数相同的十进制数 \(l\) …