在网页顶部显示阅读进度条,估算阅读时间
// ==UserScript==
// @name 网页阅读进度条
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 在网页顶部显示阅读进度条,估算阅读时间
// @author jiangchh
// @match *://*/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const READING_SPEED = 200; // 每分钟阅读字数
const PROGRESS_COLOR = '#4CAF50'; // 进度条颜色
// 添加样式
const style = document.createElement('style');
style.textContent = `
#reading-progress-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 5px;
background-color: #f0f0f0;
z-index: 9999;
}
#reading-progress-bar {
height: 100%;
width: 0;
transition: width 0.3s ease;
}
#reading-progress-info {
position: fixed;
top: 5px;
right: 10px;
background-color: rgba(255, 255, 255, 0.8);
padding: 5px 10px;
border-radius: 3px;
font-size: 12px;
z-index: 9999;
}
`;
document.head.appendChild(style);
// 创建进度条、信息元素和章节导航
function createProgressBar() {
const progressContainer = document.createElement('div');
progressContainer.id = 'reading-progress-container';
const progressBar = document.createElement('div');
progressBar.id = 'reading-progress-bar';
progressBar.style.backgroundColor = PROGRESS_COLOR;
const progressInfo = document.createElement('div');
progressInfo.id = 'reading-progress-info';
progressContainer.appendChild(progressBar);
progressContainer.appendChild(progressInfo);
document.body.appendChild(progressContainer);
}
// 估算阅读时间
function estimateReadingTime() {
const text = document.body.innerText;
const wordCount = text.trim().split(/\s+/).length;
const imageCount = document.getElementsByTagName('img').length;
const videoCount = document.getElementsByTagName('video').length;
const readingTime = wordCount / READING_SPEED + (imageCount * 10 / 60) + (videoCount * 2);
return Math.ceil(readingTime);
}
let startTime = null;
let actualReadingTime = 0;
// 更新进度条和信息
function updateProgress() {
const windowHeight = window.innerHeight;
const documentHeight = document.documentElement.scrollHeight;
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const scrollPercentage = (scrollTop / (documentHeight - windowHeight)) * 100;
const progressBar = document.getElementById('reading-progress-bar');
progressBar.style.width = scrollPercentage + '%';
const totalMinutes = estimateReadingTime();
const progressInfo = document.getElementById('reading-progress-info');
progressInfo.textContent = `已读 ${Math.round(scrollPercentage)}% | 预计阅读时间: ${totalMinutes}分钟 | 实际阅读时间: ${Math.round(actualReadingTime)}分钟`;
}
// 初始化
createProgressBar();
updateProgress(); // 初始更新
window.addEventListener('scroll', updateProgress);
window.addEventListener('resize', updateProgress);
// 每分钟更新一次实际阅读时间
setInterval(() => {
if (startTime === null) {
startTime = new Date().getTime();
} else {
const currentTime = new Date().getTime();
actualReadingTime += (currentTime - startTime) / 1000 / 60;
startTime = currentTime;
updateProgress();
}
}, 60000);
})();