- 创建js文件xxx.js引入main.js
// main.js
import '@/xxx.js';
- 创建页面埋点
// 入口vue文件(eg:app.vue)
// 自定义id方便拿取
// input标签可以利用value属性存储停留时间
<input id="log-page-key" style="display: none"/>
- 需要数据引入 && 定义
// xxx.js
// 利用路由判断进入和离开动作
import router from '@/router/index';
// 接口引入
import * as api from '@/xxxx';
// vue整体引入
import Vue from '../main.js';
// ——需要store也可引入
import store from '@/store/index';
// 来自链接
let path = '';
// 去往链接
let event_path = '';
// 注意:visitClearTimer 和 visitLeaveTimer
// 设为对象是因为计时器在开多个页面tab时会有计时器重叠计时速度变快,需要使用唯一值去接收防止计时器重叠,这里我用的是页面pagekey
// 计算停留时间定时器
let visitClearTimer = {};
// 计算离开时间定时器
let visitLeaveTimer = {};
// 离开时间
let leaveTime = 0;
- 页面埋点信息方法整合
// 编辑页面埋点信息
const setPageKey = (obj) => {
// 页面加载完毕在进行dom获取
Vue.$nextTick(() => {
// try catch 包裹防止报错影响页面进行
try {
// 取出页面埋点
let pagekey = document.getElementById('log-page-key');
let key = pagekey.getAttribute('data-key');
// 拿出pagekey判断
if (key) {
// 有
// 当前页面停留时长
if (isNaN(Number(pagekey.value))) {
// 不是数字
pagekey.value = 0;
}
else {
// 有时长
pagekey.value = Number(pagekey.value) + 100;
}
}
else {
// 没有
// 获取页面id
let str = pageID(obj);
// 使用自定义属性存入买点dom中
pagekey.setAttribute('data-key', str);
// 页面停留时长设置
pagekey.value = 0;
}
}
catch (e) {
console.log(e);
}
});
};
// 获取页面埋点信息
const getPageKey = () => {
// 获取页面埋点
let pagekey = document.getElementById('log-page-key');
// 自定义属性拿取停留时长
let key = pagekey.getAttribute('data-key');
// 停留时长处理
let num = isNaN(Number(pagekey.value)) ? 0 : Number(pagekey.value);
// 信息传出
return {
visitTime: num,
pageKey: key
};
};
// 清除页面埋点信息
const clearPageKey = (state = true) => {
// 获取页面埋点
let pagekey = document.getElementById('log-page-key');
if (state) {
// 自定义属性清除
pagekey.setAttribute('data-key', '');
}
// 页面停留时长清空
pagekey.value = 0;
};
- 页面计时器
// 页面计时器
const pageViewTime = (state) => {
// 计时器开关
if (state) {
// 页面计时器
visitClearTimer = setInterval(() => {
// 计时时间
setPageKey({});
}, 100);
}
else {
// 关闭计时器
clearInterval(visitClearTimer);
}
};
- 请求接口
const logApi = () => {
// 上传数据
};
- 有效期(如果需要离开时长有效期)
// 24小时内有效的日志
const effectiveLog = () => {
try {
// 获取埋点信息
let data = getPageKey();
visitLeaveTimer[data.pageKey] = setInterval(() => {
leaveTime += 1;
// 用户离开时间超8小时
if (leaveTime >= 480) {
// 提交离开信息
getLogData({
event_id: data.pageKey,
visit_time: data.visitTime
}, 'visitTime');
// 清除数据
clearPageKey();
// 清除定时器不重置离开时间用户再次进入时用于可以判断
clearInterval(visitLeaveTimer[[data.pageKey]]);
}
}, 60000);
}
catch (e) {
console.log(e);
}
};
- 一次用户正常进入离开
// 页面停留时长_路由后置钩子
// 用户进入页面初始化后
router.afterEach((to, from) => {
try {
// 当前跳转链接数据整理
event_path = to.path;
// 当前时间
let timestamp = Date.now();
let obj = {};
// 更新页面埋点信息
setPageKey(obj);
// 页面dom加载完成
Vue.$nextTick(() => {
// 页面埋点信息取出
let data = getPageKey();
// 进入页面请求
log(obj);
// 打开开关
pageViewTime(true);
});
}
catch (e) {
console.log(e);
}
});
// 路由守卫前置钩子
// 用户离开页面,离开之前
router.beforeEach((to, from, next) => {
try {
// 离开链接保存
if (from.path !== '/') {
path = from.path;
}
else {
path = '';
}
// 记录页面停留时长,定时器
if (path) {
let obj = {};
// 停止计时
pageViewTime(false);
// 获取页面埋点信息
let data = getPageKey();
// 清除页面埋点信息
clearPageKey();
// 离开提交
log(obj);
}
}
catch (e) {
console.log(e);
}
next();
});
- 特殊情况——直接关闭
// 页面关闭事件
// 关闭事件同步事件可以执行,异步事件无法执行
window.addEventListener('beforeunload', (event) => {
try {
let arr = JSON.parse(localStorage.getItem('leavePageData'));
pageViewTime(false);
// 获取页面埋点信息
let data = getPageKey();
// 停留时长
let remainTime = data.visitTime;
// 没有当前页面
// 收集离开信息
let obj = {
visit_time: remainTime,
event_id: data.pageKey
};
arr.push(obj);
// 直接提交离开信息
localStorage.setItem('leavePageData', JSON.stringify(arr))
// 清除页面埋点信息
clearPageKey();
}
catch (e) {
console.log(e);
}
});
// 离开存储的数据进行提交
if (localStorage.getItem('leavePageData')) {
try {
// 存在
let arr = JSON.parse(localStorage.getItem('leavePageData'));
arr.forEach(i => {
getLogData(i, 'visitTime');
});
localStorage.setItem('leavePageData', JSON.stringify([]));
}
catch (e) {
console.log(e);
}
}
else {
localStorage.setItem('leavePageData', JSON.stringify([]));
}
- 特殊情况——页面切换
// 切换页面事件
window.addEventListener('visibilitychange', (e) => {
try {
if (document.hidden) {
// 停止计时
pageViewTime(false);
// 离开时间计时
effectiveLog();
}
else {
// 超过有效期
if (leaveTime >= 480) {
// 用户离开时间超8小时
// 离开超时已在计时器中做判定,防止用户打开页面后没有进行回来操作
// 清除计时器计时,满足条件后在进行清零,否则无法满足条件计算新页面访问时长
leaveTime = 0;
// 编辑页面埋点
setPageKey({
timestamp: Date.now(),
event_path: router.history.current.path
});
// 页面重新计时
pageViewTime(true);
// 收集数据
let data = getPageKey();
// 如果有任务id
let obj = {
timestamp: Date.now(),
event_path: Vue.$route.fullPath,
event_type: 'pv',
event_id: data.pageKey,
};
// 提交进入信息
getLogData(obj, 'pv');
}
else {
// 取页面埋点
let data = getPageKey();
// 离开时间没有超过8小时——继续计时
pageViewTime(true);
// 清除离开定时器计时
leaveTime = 0;
// 清除离开定时器
clearInterval(visitLeaveTimer[[data.pageKey]]);
}
}
}
catch (e) {
console.log(e);
}
});