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+ }
0 commit comments