// ==UserScript== // @name 页面时间追踪器及摘要与饼图 // @name:zh 页面时间追踪器及摘要与饼图 // @name:en Page Time Tracker with Summary and Pie Chart // @namespace http://tampermonkey.net/ // @license MIT // @version 1.6 // @description 在标题栏中显示页面上的花费时间,按域名分组,显示摘要并包括百分比的饼图,并允许删除数据 // @description:en Track and display time spent on the page in the title bar, group by domain, show a summary with a pie chart including percentages, and allow data deletion // @author Your Name // @match *://*/* // @grant GM_setValue // @grant GM_getValue // @grant GM_openInTab // @grant GM_registerMenuCommand // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 初始化开始时间和原始标题 const startTime = new Date(); const originalTitle = document.title; // 格式化时间为分钟和秒 function formatTimeMS(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; return `${minutes}m ${remainingSeconds}s`; } // 更新标题栏中的时间 function updateTitle() { const currentTime = new Date(); const timeSpent = Math.floor((currentTime - startTime) / 1000); const formattedTime = formatTimeMS(timeSpent); document.title = `${originalTitle} - ${formattedTime}`; } // 存储访问数据 function storeVisit() { const endTime = new Date(); const timeSpent = Math.floor((endTime - startTime) / 1000); const pageData = { url: window.location.href, title: originalTitle, timeSpent: timeSpent, date: startTime.toDateString() }; let visits = GM_getValue('pageVisits', []); visits.push(pageData); GM_setValue('pageVisits', visits); } // 获取域名 function getDomain(url) { const a = document.createElement('a'); a.href = url; return a.hostname; } // 清除旧数据(仅保留当天的数据) function clearOldData() { const today = new Date().toDateString(); let visits = GM_getValue('pageVisits', []); visits = visits.filter(visit => visit.date === today); GM_setValue('pageVisits', visits); } // 删除所有数据 function deleteAllData() { GM_setValue('pageVisits', []); alert('所有访问数据已被删除。'); } // 每天清除一次旧数据 const lastClearTime = GM_getValue('lastClearTime', ''); const today = new Date().toDateString(); if (lastClearTime !== today) { clearOldData(); GM_setValue('lastClearTime', today); } // 在页面卸载时存储访问数据 window.addEventListener('beforeunload', storeVisit); // 每秒更新一次标题栏中的时间 setInterval(() => { updateTitle(); }, 1000); // 注册菜单命令以显示每日摘要 GM_registerMenuCommand('显示每日摘要', function() { const summaryPageContent = generateSummaryPage(); const summaryWindow = window.open('', '_blank'); summaryWindow.document.write(summaryPageContent); summaryWindow.document.close(); }); // 注册菜单命令以删除所有数据 GM_registerMenuCommand('删除所有数据', deleteAllData); // 生成摘要页面 function generateSummaryPage() { const visits = GM_getValue('pageVisits', []); const today = new Date().toDateString(); const todayVisits = visits.filter(visit => visit.date === today); // 按域名分组访问数据 const domainVisits = todayVisits.reduce((acc, visit) => { const domain = getDomain(visit.url); if (!acc[domain]) { acc[domain] = { domain, timeSpent: 0, pages: [] }; } acc[domain].timeSpent += visit.timeSpent; acc[domain].pages.push(visit); return acc; }, {}); const totalSeconds = Object.values(domainVisits).reduce((sum, domain) => sum + domain.timeSpent, 0); let summaryHTML = '每日摘要'; summaryHTML += '

每日摘要

'; summaryHTML += ''; Object.values(domainVisits).forEach(domain => { const percentage = ((domain.timeSpent / totalSeconds) * 100).toFixed(2); summaryHTML += ``; }); summaryHTML += '
域名花费时间百分比
${domain.domain}${formatTimeMS(domain.timeSpent)}${percentage}%
'; summaryHTML += ''; summaryHTML += ''; summaryHTML += ''; summaryHTML += ''; return summaryHTML; } })();