Skip to content

Commit b9be3c7

Browse files
committed
支持阅读进度条close #14
1 parent e0477cd commit b9be3c7

3 files changed

Lines changed: 183 additions & 2 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* 进度条容器 */
2+
#reading-progress-container {
3+
position: fixed;
4+
top: 0;
5+
left: 0;
6+
width: 100%;
7+
height: 4px;
8+
background-color: rgba(229, 231, 235, 0.3); /* 浅灰色背景 */
9+
z-index: 9999;
10+
}
11+
12+
/* 进度条 */
13+
#reading-progress-bar {
14+
height: 100%;
15+
background: linear-gradient(to right, #3b82f6, #60a5fa);
16+
width: 0%;
17+
transition: width 0.1s ease;
18+
}
19+
20+
/* 进度指示器 */
21+
#reading-progress-indicator {
22+
position: fixed;
23+
right: 5rem;
24+
bottom: 1rem;
25+
background-color: rgba(31, 41, 55, 0.8);
26+
color: white;
27+
padding: 0.5rem 0.75rem;
28+
border-radius: 9999px;
29+
font-size: 0.875rem;
30+
font-weight: 500;
31+
opacity: 0.8;
32+
transition: opacity 0.2s ease;
33+
cursor: pointer;
34+
z-index: 9999;
35+
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
36+
}
37+
38+
#reading-progress-indicator:hover {
39+
opacity: 1;
40+
}
41+
42+
#reading-progress-indicator.hidden {
43+
opacity: 0;
44+
pointer-events: none;
45+
}
46+
47+
/* 暗黑模式下的样式 */
48+
.dark #reading-progress-container {
49+
background-color: rgba(55, 65, 81, 0.3);
50+
}
51+
52+
.dark #reading-progress-bar {
53+
background: linear-gradient(to right, #60a5fa, #93c5fd);
54+
}
55+
56+
.dark #reading-progress-indicator {
57+
background-color: rgba(55, 65, 81, 0.9);
58+
}
59+
60+
/* 在移动设备上调整样式 */
61+
@media (max-width: 768px) {
62+
#reading-progress-bar {
63+
height: 5px;
64+
}
65+
66+
#reading-progress-indicator {
67+
font-size: 0.75rem;
68+
padding: 0.35rem 0.6rem;
69+
}
70+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/**
2+
* 初始化高级阅读进度条
3+
* 包含顶部进度条和悬浮百分比显示
4+
*/
5+
function initAdvancedReadingProgress() {
6+
// 创建容器元素
7+
const progressContainer = document.createElement('div');
8+
progressContainer.id = 'reading-progress-container';
9+
10+
// 创建进度条元素
11+
const progressBar = document.createElement('div');
12+
progressBar.id = 'reading-progress-bar';
13+
14+
// 创建百分比显示元素
15+
const progressIndicator = document.createElement('div');
16+
progressIndicator.id = 'reading-progress-indicator';
17+
progressIndicator.className = 'fixed right-4 bottom-4 bg-gray-800 dark:bg-gray-700 text-white px-3 py-2 rounded-full text-sm font-medium opacity-80 hover:opacity-100 transition-opacity';
18+
progressIndicator.innerHTML = '0%';
19+
20+
// 添加元素到页面
21+
progressContainer.appendChild(progressBar);
22+
document.body.appendChild(progressContainer);
23+
document.body.appendChild(progressIndicator);
24+
25+
// 获取内容元素 - 假设文章内容在 .article-content 类的元素中
26+
const contentElement = document.querySelector('.article-content') || document.querySelector('main') || document.body;
27+
28+
// 存储原始标题
29+
const originalTitle = document.title;
30+
31+
// 计算内容区域的位置和高度
32+
const getContentHeight = () => {
33+
const contentRect = contentElement.getBoundingClientRect();
34+
const contentTop = contentRect.top + window.scrollY;
35+
const contentHeight = contentRect.height;
36+
37+
// 考虑到页脚和其他元素的高度,我们通常只计算到页面底部前的一部分
38+
const visibleContentHeight = contentHeight - window.innerHeight;
39+
40+
return {
41+
start: contentTop,
42+
height: visibleContentHeight
43+
};
44+
};
45+
46+
// 创建节流函数以减少更新频率
47+
function throttle(callback, limit) {
48+
let waiting = false;
49+
return function () {
50+
if (!waiting) {
51+
callback.apply(this, arguments);
52+
waiting = true;
53+
setTimeout(function () {
54+
waiting = false;
55+
}, limit);
56+
}
57+
};
58+
}
59+
60+
// 更新进度条和指示器
61+
function updateProgress() {
62+
const content = getContentHeight();
63+
const scrolled = window.scrollY - content.start;
64+
65+
// 计算阅读进度百分比
66+
let progressPercent = 0;
67+
if (scrolled > 0) {
68+
progressPercent = Math.min(100, Math.max(0, (scrolled / content.height) * 100));
69+
}
70+
71+
// 舍入到整数用于显示
72+
const displayPercent = Math.round(progressPercent);
73+
74+
// 更新进度条宽度
75+
progressBar.style.width = `${progressPercent}%`;
76+
77+
// 更新百分比指示器
78+
progressIndicator.textContent = `${displayPercent}%`;
79+
80+
// 根据进度显示或隐藏指示器
81+
if (displayPercent > 0 && displayPercent < 100) {
82+
progressIndicator.classList.remove('hidden');
83+
}
84+
else {
85+
progressIndicator.classList.add('hidden');
86+
}
87+
}
88+
89+
// 使用节流函数减少更新频率,每100毫秒更新一次
90+
const throttledUpdateProgress = throttle(updateProgress, 100);
91+
92+
// 添加事件监听器
93+
window.addEventListener('scroll', throttledUpdateProgress, {passive: true});
94+
window.addEventListener('resize', throttledUpdateProgress, {passive: true});
95+
96+
// 初始调用一次以设置初始状态
97+
updateProgress();
98+
99+
// 点击百分比指示器时滚动到顶部
100+
progressIndicator.addEventListener('click', function () {
101+
window.scrollTo({top: 0, behavior: 'smooth'});
102+
});
103+
}
104+
105+
// 当页面加载完成后初始化进度条
106+
if (document.readyState === 'complete') {
107+
initAdvancedReadingProgress();
108+
}
109+
else {
110+
window.addEventListener('load', initAdvancedReadingProgress);
111+
}

templates/components/issues.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ module.exports = function template(item) {
88
<a href="${item.href}"
99
target="_blank"
1010
class="inline-flex items-center px-2.5 py-1.5 rounded-md bg-gray-100 hover:bg-gray-200 text-gray-900 dark:bg-gray-800 dark:hover:bg-gray-700 dark:text-gray-100 transition-colors duration-200 no-underline max-w-md">
11-
<svg class="w-5 h-5 mr-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
11+
<svg class="w-4 h-4 mr-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1212
<path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"></path>
1313
<path d="M9 18c-4.51 2-5-2-7-2"></path>
1414
</svg>
1515
<span class="flex-1">
1616
<span class="font-semibold">${owner}/${repo}</span>
1717
<span class="inline-flex items-center ml-1">
18-
<span class="w-4 h-4 inline-flex items-center justify-center bg-gray-600 dark:bg-gray-400 rounded-full text-white text-xs mr-1">
18+
<span class="w-3 h-3 inline-flex items-center justify-center bg-gray-600 dark:bg-gray-400 rounded-full text-white text-xs mr-1">
1919
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="12" height="12" fill="currentColor">
2020
<path d="M8 9.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path>
2121
<path fill-rule="evenodd" d="M8 0a8 8 0 100 16A8 8 0 008 0zM1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0z"></path>

0 commit comments

Comments
 (0)