hexo-theme-solitude 1.8.10 → 1.8.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_config.yml +1 -0
- package/languages/default.yml +3 -0
- package/languages/en.yml +3 -0
- package/languages/zh-CN.yml +3 -0
- package/languages/zh-TW.yml +3 -0
- package/layout/includes/footer.pug +1 -1
- package/layout/includes/head/page_config.pug +1 -1
- package/layout/includes/inject/body.pug +5 -5
- package/layout/includes/inject/head.pug +1 -1
- package/layout/includes/page/music.pug +6 -1
- package/layout/includes/widgets/aside/asideWebInfo.pug +12 -4
- package/layout/includes/widgets/home/carousel.pug +27 -21
- package/layout/includes/widgets/post/post-ai.pug +2 -2
- package/layout/includes/widgets/post/postMeta.pug +6 -2
- package/layout/includes/widgets/third-party/comments/artalk.pug +3 -3
- package/layout/includes/widgets/third-party/comments/twikoo.pug +4 -2
- package/layout/includes/widgets/third-party/comments/valine.pug +5 -3
- package/layout/includes/widgets/third-party/comments/waline.pug +4 -2
- package/package.json +1 -1
- package/plugins.yml +5 -1
- package/source/css/_layout/header.styl +7 -6
- package/source/css/_page/_home/carousel.styl +73 -89
- package/source/css/_page/links.styl +1 -1
- package/source/js/barrage_comment.js +63 -70
- package/source/js/covercolor/api.js +35 -52
- package/source/js/covercolor/local.js +22 -27
- package/source/js/main.js +473 -566
- package/source/js/music.js +15 -5
- package/source/js/right_menu.js +38 -47
- package/source/js/search/local.js +16 -11
- package/source/js/utils.js +109 -136
package/source/js/main.js
CHANGED
@@ -1,39 +1,31 @@
|
|
1
|
+
// 移动端侧栏
|
1
2
|
const sidebarFn = () => {
|
2
|
-
const $toggleMenu = document.getElementById('toggle-menu')
|
3
|
-
const $mobileSidebarMenus = document.getElementById('sidebar-menus')
|
4
|
-
const $menuMask = document.getElementById('menu-mask')
|
5
|
-
const $body = document.body
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
$body.style.
|
10
|
-
utils
|
11
|
-
$mobileSidebarMenus.classList
|
12
|
-
}
|
13
|
-
|
14
|
-
function closeMobileSidebar() {
|
15
|
-
$body.style.overflow = ''
|
16
|
-
$body.style.paddingRight = ''
|
17
|
-
utils.fadeOut($menuMask, 0.5)
|
18
|
-
$mobileSidebarMenus.classList.remove('open')
|
3
|
+
const $toggleMenu = document.getElementById('toggle-menu');
|
4
|
+
const $mobileSidebarMenus = document.getElementById('sidebar-menus');
|
5
|
+
const $menuMask = document.getElementById('menu-mask');
|
6
|
+
const $body = document.body;
|
7
|
+
const toggleMobileSidebar = (isOpen) => {
|
8
|
+
utils.sidebarPaddingR();
|
9
|
+
$body.style.overflow = isOpen ? 'hidden' : '';
|
10
|
+
$body.style.paddingRight = isOpen ? '' : '';
|
11
|
+
utils[isOpen ? 'fadeIn' : 'fadeOut']($menuMask, 0.5);
|
12
|
+
$mobileSidebarMenus.classList[isOpen ? 'add' : 'remove']('open');
|
19
13
|
}
|
20
|
-
|
21
|
-
$
|
22
|
-
|
23
|
-
$menuMask.addEventListener('click', e => {
|
14
|
+
$toggleMenu.addEventListener('click', () => toggleMobileSidebar(true));
|
15
|
+
$menuMask.addEventListener('click', () => {
|
24
16
|
if ($mobileSidebarMenus.classList.contains('open')) {
|
25
|
-
|
17
|
+
toggleMobileSidebar(false);
|
26
18
|
}
|
27
|
-
})
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
if ($mobileSidebarMenus.classList.contains('open')) closeMobileSidebar()
|
19
|
+
});
|
20
|
+
window.addEventListener('resize', () => {
|
21
|
+
if (utils.isHidden($toggleMenu) && $mobileSidebarMenus.classList.contains('open')) {
|
22
|
+
toggleMobileSidebar(false);
|
32
23
|
}
|
33
24
|
sco.refreshWaterFall();
|
34
|
-
})
|
25
|
+
});
|
35
26
|
}
|
36
27
|
|
28
|
+
// 滚动事件监听
|
37
29
|
const scrollFn = function () {
|
38
30
|
const innerHeight = window.innerHeight;
|
39
31
|
if (document.body.scrollHeight <= innerHeight) return;
|
@@ -54,12 +46,13 @@ const scrollFn = function () {
|
|
54
46
|
$header.classList.remove('nav-fixed', 'nav-visible');
|
55
47
|
}
|
56
48
|
}, 200);
|
57
|
-
window.addEventListener('scroll', function(e) {
|
49
|
+
window.addEventListener('scroll', function (e) {
|
58
50
|
throttledScroll(e);
|
59
51
|
if (window.scrollY === 0) {
|
60
52
|
$header.classList.remove('nav-fixed', 'nav-visible');
|
61
53
|
}
|
62
54
|
});
|
55
|
+
|
63
56
|
function scrollDirection(currentTop) {
|
64
57
|
const result = currentTop > initTop;
|
65
58
|
initTop = currentTop;
|
@@ -67,213 +60,154 @@ const scrollFn = function () {
|
|
67
60
|
}
|
68
61
|
}
|
69
62
|
|
63
|
+
// 进度球
|
70
64
|
const percent = () => {
|
71
65
|
const docEl = document.documentElement;
|
72
66
|
const body = document.body;
|
73
67
|
const scrollPos = window.pageYOffset || docEl.scrollTop;
|
74
|
-
const
|
75
|
-
const viewportHeight = docEl.clientHeight;
|
76
|
-
const totalScrollableHeight = scrollHeight - viewportHeight;
|
68
|
+
const totalScrollableHeight = Math.max(body.scrollHeight, docEl.scrollHeight, body.offsetHeight, docEl.offsetHeight, body.clientHeight, docEl.clientHeight) - docEl.clientHeight;
|
77
69
|
const scrolledPercent = Math.round((scrollPos / totalScrollableHeight) * 100);
|
78
70
|
const navToTop = document.querySelector("#nav-totop");
|
79
71
|
const percentDisplay = document.querySelector("#percent");
|
80
|
-
const
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
percentDisplay.textContent = GLOBAL_CONFIG.lang.backtop;
|
85
|
-
} else {
|
86
|
-
navToTop.classList.remove("long");
|
87
|
-
percentDisplay.textContent = scrolledPercent;
|
88
|
-
}
|
89
|
-
const elementsToHide = document.querySelectorAll(".needEndHide");
|
90
|
-
elementsToHide.forEach(item => item.classList.toggle("hide", totalScrollableHeight - scrollPos < 100));
|
91
|
-
window.onscroll = percent
|
92
|
-
}
|
93
|
-
|
94
|
-
const handleThemeChange = mode => {
|
95
|
-
const globalFn = window.globalFn || {}
|
96
|
-
const themeChange = globalFn.themeChange || {}
|
97
|
-
if (!themeChange) {
|
98
|
-
return
|
99
|
-
}
|
100
|
-
|
101
|
-
Object.keys(themeChange).forEach(key => {
|
102
|
-
const themeChangeFn = themeChange[key]
|
103
|
-
themeChangeFn(mode)
|
104
|
-
})
|
72
|
+
const isNearEnd = (window.scrollY + docEl.clientHeight) >= (document.getElementById("post-comment") || document.getElementById("footer")).offsetTop;
|
73
|
+
navToTop.classList.toggle("long", isNearEnd || scrolledPercent > 90);
|
74
|
+
percentDisplay.textContent = isNearEnd || scrolledPercent > 90 ? GLOBAL_CONFIG.lang.backtop : scrolledPercent;
|
75
|
+
document.querySelectorAll(".needEndHide").forEach(item => item.classList.toggle("hide", totalScrollableHeight - scrollPos < 100));
|
105
76
|
}
|
106
77
|
|
78
|
+
// 展示今日卡片
|
107
79
|
const showTodayCard = () => {
|
108
|
-
const el = document.getElementById('todayCard')
|
109
|
-
const topGroup = document.
|
110
|
-
|
111
|
-
if (el && topGroup) {
|
112
|
-
topGroup.addEventListener('mouseleave', () => {
|
113
|
-
el.classList.remove('hide')
|
114
|
-
})
|
115
|
-
}
|
80
|
+
const el = document.getElementById('todayCard');
|
81
|
+
const topGroup = document.querySelector('.topGroup');
|
82
|
+
topGroup?.addEventListener('mouseleave', () => el?.classList.remove('hide'));
|
116
83
|
}
|
117
84
|
|
85
|
+
// 初始化 IntersectionObserver
|
118
86
|
const initObserver = () => {
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
function handleIntersection(entries) {
|
123
|
-
entries.forEach(function (entry) {
|
124
|
-
if (entry.isIntersecting) {
|
125
|
-
paginationElement.classList.add("show-window");
|
126
|
-
GLOBAL_CONFIG.comment.commentBarrage && (document.querySelector(".comment-barrage").style.bottom = "-200px");
|
127
|
-
} else {
|
128
|
-
paginationElement.classList.remove("show-window");
|
129
|
-
GLOBAL_CONFIG.comment.commentBarrage && (document.querySelector(".comment-barrage").style.bottom = "0px");
|
130
|
-
}
|
131
|
-
});
|
132
|
-
}
|
133
|
-
|
87
|
+
const commentElement = document.getElementById("post-comment");
|
88
|
+
const paginationElement = document.getElementById("pagination");
|
89
|
+
const commentBarrageElement = document.querySelector(".comment-barrage");
|
134
90
|
if (commentElement && paginationElement) {
|
135
|
-
|
91
|
+
const observer = new IntersectionObserver(entries => {
|
92
|
+
entries.forEach(entry => {
|
93
|
+
const action = entry.isIntersecting ? 'add' : 'remove';
|
94
|
+
paginationElement.classList[action]("show-window");
|
95
|
+
if (GLOBAL_CONFIG.comment.commentBarrage) {
|
96
|
+
commentBarrageElement.style.bottom = entry.isIntersecting ? "-200px" : "0px";
|
97
|
+
}
|
98
|
+
});
|
99
|
+
});
|
136
100
|
observer.observe(commentElement);
|
137
101
|
}
|
102
|
+
};
|
103
|
+
|
104
|
+
// 复制版权信息
|
105
|
+
const addCopyright = () => {
|
106
|
+
if (!GLOBAL_CONFIG.copyright) return;
|
107
|
+
const {limit, author, link, source, info} = GLOBAL_CONFIG.copyright;
|
108
|
+
document.body.addEventListener('copy', (e) => {
|
109
|
+
e.preventDefault();
|
110
|
+
const copyText = window.getSelection().toString();
|
111
|
+
const text = copyText.length > limit ? `${copyText}\n\n${author}\n${link}${window.location.href}\n${source}\n${info}` : copyText;
|
112
|
+
e.clipboardData.setData('text', text);
|
113
|
+
});
|
114
|
+
};
|
115
|
+
|
116
|
+
// 侧边栏状态
|
117
|
+
const asideStatus = () => {
|
118
|
+
const status = utils.saveToLocal.get('aside-status');
|
119
|
+
document.documentElement.classList.toggle('hide-aside', status === 'hide');
|
138
120
|
}
|
139
121
|
|
122
|
+
// 初始化主题色
|
140
123
|
function initThemeColor() {
|
141
124
|
const currentTop = window.scrollY || document.documentElement.scrollTop;
|
142
|
-
|
143
|
-
|
144
|
-
themeColor = getComputedStyle(document.documentElement).getPropertyValue('--efu-card-bg');
|
145
|
-
} else if (PAGE_CONFIG.is_post) {
|
146
|
-
themeColor = getComputedStyle(document.documentElement).getPropertyValue('--efu-main');
|
147
|
-
} else {
|
148
|
-
themeColor = getComputedStyle(document.documentElement).getPropertyValue('--efu-background');
|
149
|
-
}
|
150
|
-
changeThemeColor(themeColor);
|
125
|
+
const themeColor = currentTop > 0 ? '--efu-card-bg' : PAGE_CONFIG.is_post ? '--efu-main' : '--efu-background';
|
126
|
+
applyThemeColor(getComputedStyle(document.documentElement).getPropertyValue(themeColor));
|
151
127
|
}
|
152
128
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
129
|
+
/**
|
130
|
+
* applyThemeColor
|
131
|
+
* @description 应用主题色
|
132
|
+
* @param color
|
133
|
+
*/
|
134
|
+
function applyThemeColor(color) {
|
135
|
+
const themeColorMeta = document.querySelector('meta[name="theme-color"]');
|
136
|
+
const appleMobileWebAppMeta = document.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]');
|
137
|
+
themeColorMeta?.setAttribute("content", color);
|
138
|
+
appleMobileWebAppMeta?.setAttribute("content", color);
|
139
|
+
if (window.matchMedia("(display-mode: standalone)").matches) {
|
140
|
+
document.body.style.backgroundColor = color;
|
159
141
|
}
|
160
142
|
}
|
161
143
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
e.addEventListener('click', (event) => {
|
172
|
-
event.preventDefault()
|
173
|
-
utils.scrollToDest(utils.getEleTop(document.getElementById(decodeURI((event.target.className === 'toc-text' ? event.target.parentNode.hash : event.target.hash).replace('#', '')))), 300)
|
174
|
-
})
|
175
|
-
})
|
176
|
-
this.active(el)
|
177
|
-
}
|
178
|
-
|
179
|
-
static active(toc) {
|
180
|
-
const $article = document.getElementById('article-container')
|
181
|
-
const $tocContent = document.getElementById('toc-content')
|
182
|
-
const list = $article.querySelectorAll('h1,h2,h3,h4,h5,h6')
|
183
|
-
let detectItem = ''
|
184
|
-
|
185
|
-
function autoScroll(el) {
|
186
|
-
const activePosition = el.getBoundingClientRect().top
|
187
|
-
const sidebarScrollTop = $tocContent.scrollTop
|
188
|
-
if (activePosition > (document.documentElement.clientHeight - 100)) {
|
189
|
-
$tocContent.scrollTop = sidebarScrollTop + 150
|
190
|
-
}
|
191
|
-
if (activePosition < 100) {
|
192
|
-
$tocContent.scrollTop = sidebarScrollTop - 150
|
193
|
-
}
|
194
|
-
}
|
195
|
-
|
196
|
-
function findHeadPosition(top) {
|
197
|
-
if (top === 0) {
|
198
|
-
return false
|
199
|
-
}
|
200
|
-
|
201
|
-
let currentIndex = ''
|
202
|
-
|
203
|
-
list.forEach(function (ele, index) {
|
204
|
-
if (top > utils.getEleTop(ele) - 80) {
|
205
|
-
currentIndex = index
|
206
|
-
}
|
207
|
-
})
|
208
|
-
|
209
|
-
if (detectItem === currentIndex) return
|
210
|
-
detectItem = currentIndex
|
211
|
-
document.querySelectorAll('.toc .active').forEach((i) => {
|
212
|
-
i.classList.remove('active')
|
213
|
-
})
|
214
|
-
const activeitem = toc[detectItem]
|
215
|
-
if (activeitem) {
|
216
|
-
let parent = toc[detectItem].parentNode
|
217
|
-
activeitem.classList.add('active')
|
218
|
-
autoScroll(activeitem)
|
219
|
-
for (; !parent.matches('.toc'); parent = parent.parentNode) {
|
220
|
-
if (parent.matches('li')) parent.classList.add('active')
|
221
|
-
}
|
222
|
-
}
|
223
|
-
}
|
224
|
-
|
225
|
-
window.tocScrollFn = utils.throttle(function () {
|
226
|
-
const currentTop = window.scrollY || document.documentElement.scrollTop
|
227
|
-
findHeadPosition(currentTop)
|
228
|
-
}, 100)
|
229
|
-
|
230
|
-
window.addEventListener('scroll', tocScrollFn)
|
144
|
+
/**
|
145
|
+
* handleThemeChange
|
146
|
+
* @description 切换主题色
|
147
|
+
* @param mode
|
148
|
+
*/
|
149
|
+
const handleThemeChange = mode => {
|
150
|
+
const themeChange = window.globalFn?.themeChange || {}
|
151
|
+
for (let key in themeChange) {
|
152
|
+
themeChange[key](mode)
|
231
153
|
}
|
232
154
|
}
|
233
155
|
|
156
|
+
// lastSayHello 上次打招呼的内容
|
234
157
|
let lastSayHello = "";
|
235
|
-
|
158
|
+
// musicPlaying 是否正在播放音乐
|
159
|
+
let musicPlaying = false
|
160
|
+
// is_rm 是否启用右键菜单
|
236
161
|
let is_rm = typeof rm !== 'undefined'
|
237
162
|
|
163
|
+
/**
|
164
|
+
* sco
|
165
|
+
* @description solitude 主题的一些方法
|
166
|
+
* @type {{showConsole: (function(): boolean), setTimeState: sco.setTimeState, toTop: (function(): void), changeTimeFormat(*): void, hideCookie: sco.hideCookie, owoBig(*): void, switchDarkMode: sco.switchDarkMode, openAllTags: sco.openAllTags, switchHideAside: sco.switchHideAside, addRuntime: sco.addRuntime, refreshWaterFall: sco.refreshWaterFall, categoriesBarActive: sco.categoriesBarActive, addNavBackgroundInit: sco.addNavBackgroundInit, toPage: sco.toPage, changeSayHelloText: sco.changeSayHelloText, initConsoleState: (function(): void), switchComments(): void, switchKeyboard: sco.switchKeyboard, initAdjust: sco.initAdjust, listenToPageInputPress: sco.listenToPageInputPress, scrollTo: sco.scrollTo, musicToggle: sco.musicToggle, toTalk: sco.toTalk, switchCommentBarrage: sco.switchCommentBarrage, hideTodayCard: (function(): void), scrollCategoryBarToRight: sco.scrollCategoryBarToRight, scrollToComment: sco.scrollToComment, initbbtalk: sco.initbbtalk, tagPageActive: sco.tagPageActive, hideConsole: (function(): void), addPhotoFigcaption: sco.addPhotoFigcaption}}
|
167
|
+
*/
|
238
168
|
let sco = {
|
169
|
+
/**
|
170
|
+
* hideCookie
|
171
|
+
* @description 隐藏 cookie 通知
|
172
|
+
*/
|
239
173
|
hideCookie: function () {
|
240
|
-
|
241
|
-
|
242
|
-
|
174
|
+
const cookiesWindow = document.getElementById("cookies-window");
|
175
|
+
if (cookiesWindow) {
|
176
|
+
setTimeout(() => {
|
243
177
|
cookiesWindow.classList.add("cw-hide");
|
244
|
-
setTimeout(() =>
|
245
|
-
|
246
|
-
|
247
|
-
}
|
248
|
-
}, 3000);
|
178
|
+
setTimeout(() => cookiesWindow.style.display = "none", 1000);
|
179
|
+
}, 3000);
|
180
|
+
}
|
249
181
|
},
|
182
|
+
/**
|
183
|
+
* scrollTo
|
184
|
+
* @description 滚动到指定元素
|
185
|
+
* @param elementId
|
186
|
+
*/
|
250
187
|
scrollTo: function (elementId) {
|
251
188
|
const targetElement = document.getElementById(elementId);
|
252
189
|
if (targetElement) {
|
253
190
|
const targetPosition = targetElement.getBoundingClientRect().top + window.pageYOffset - 80;
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
animationStartTime = animationStartTime || currentTime;
|
259
|
-
const elapsedTime = currentTime - animationStartTime;
|
260
|
-
const progressRatio = Math.min(elapsedTime / 0, 1);
|
261
|
-
const easing = progressRatio < .5 ? 2 * progressRatio * progressRatio : (4 - 2 * progressRatio) * progressRatio - 1;
|
262
|
-
window.scrollTo(0, startPosition + distanceToScroll * easing);
|
263
|
-
elapsedTime < 600 && window.requestAnimationFrame(smoothScroll);
|
264
|
-
}));
|
191
|
+
window.scroll({
|
192
|
+
top: targetPosition,
|
193
|
+
behavior: "smooth"
|
194
|
+
});
|
265
195
|
}
|
266
196
|
},
|
197
|
+
/**
|
198
|
+
* musicToggle
|
199
|
+
* @description 音乐播放开关
|
200
|
+
*/
|
267
201
|
musicToggle: function () {
|
268
202
|
const $music = document.querySelector('#nav-music');
|
269
203
|
const $meting = document.querySelector('meting-js');
|
270
204
|
const $console = document.getElementById('consoleMusic');
|
271
205
|
const $rm_text = document.querySelector('#menu-music-toggle span');
|
272
206
|
const $rm_icon = document.querySelector('#menu-music-toggle i');
|
273
|
-
|
274
|
-
$music.classList.toggle("playing",
|
275
|
-
$console.classList.toggle("on",
|
276
|
-
if (
|
207
|
+
musicPlaying = !musicPlaying;
|
208
|
+
$music.classList.toggle("playing", musicPlaying);
|
209
|
+
$console.classList.toggle("on", musicPlaying);
|
210
|
+
if (musicPlaying) {
|
277
211
|
$meting.aplayer.play();
|
278
212
|
rm?.menuItems.music[0] && ($rm_text.textContent = GLOBAL_CONFIG.right_menu.music.stop) && ($rm_icon.className = 'solitude st-pause-fill')
|
279
213
|
} else {
|
@@ -281,113 +215,145 @@ let sco = {
|
|
281
215
|
rm?.menuItems.music[0] && ($rm_text.textContent = GLOBAL_CONFIG.right_menu.music.start) && ($rm_icon.className = 'solitude st-play-fill')
|
282
216
|
}
|
283
217
|
},
|
218
|
+
/**
|
219
|
+
* switchCommentBarrage
|
220
|
+
* @description 切换评论弹幕
|
221
|
+
*/
|
284
222
|
switchCommentBarrage: function () {
|
285
223
|
let commentBarrageElement = document.querySelector(".comment-barrage");
|
286
|
-
if (commentBarrageElement)
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
} else {
|
293
|
-
commentBarrageElement.style.display = "flex";
|
294
|
-
document.querySelector("#consoleCommentBarrage").classList.add("on");
|
295
|
-
utils.saveToLocal.set("commentBarrageSwitch", true, .2);
|
296
|
-
rm?.menuItems.barrage && rm.barrage(false)
|
297
|
-
}
|
298
|
-
}
|
224
|
+
if (!commentBarrageElement) return;
|
225
|
+
const isDisplayed = window.getComputedStyle(commentBarrageElement).display === "flex";
|
226
|
+
commentBarrageElement.style.display = isDisplayed ? "none" : "flex";
|
227
|
+
document.querySelector("#consoleCommentBarrage").classList.toggle("on", !isDisplayed);
|
228
|
+
utils.saveToLocal.set("commentBarrageSwitch", !isDisplayed, .2);
|
229
|
+
rm?.menuItems.barrage && rm.barrage(isDisplayed)
|
299
230
|
},
|
231
|
+
/**
|
232
|
+
* switchHideAside
|
233
|
+
* @description 切换侧边栏
|
234
|
+
*/
|
300
235
|
switchHideAside: function () {
|
301
236
|
const htmlClassList = document.documentElement.classList;
|
302
|
-
|
237
|
+
const consoleHideAside = document.querySelector("#consoleHideAside");
|
238
|
+
const isHideAside = htmlClassList.contains("hide-aside");
|
239
|
+
utils.saveToLocal.set("aside-status", isHideAside ? "show" : "hide", 1);
|
303
240
|
htmlClassList.toggle("hide-aside");
|
304
|
-
|
241
|
+
consoleHideAside.classList.toggle("on", !isHideAside);
|
305
242
|
},
|
243
|
+
/**
|
244
|
+
* switchKeyboard
|
245
|
+
* @description 切换快捷键
|
246
|
+
*/
|
306
247
|
switchKeyboard: function () {
|
307
248
|
sco_keyboards = !sco_keyboards;
|
308
249
|
const consoleKeyboard = document.querySelector("#consoleKeyboard");
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
closeKeyboard()
|
315
|
-
consoleKeyboard.classList.remove("on");
|
316
|
-
localStorage.setItem("keyboard", false);
|
317
|
-
document.getElementById('keyboard-tips')?.classList.remove('show')
|
318
|
-
}
|
319
|
-
},
|
320
|
-
initConsoleState: function () {
|
321
|
-
document.documentElement.classList.contains("hide-aside") ? document.querySelector("#consoleHideAside").classList.add("on") : document.querySelector("#consoleHideAside").classList.remove("on")
|
250
|
+
const keyboardFunction = sco_keyboards ? openKeyboard : closeKeyboard;
|
251
|
+
consoleKeyboard.classList.toggle("on", sco_keyboards);
|
252
|
+
keyboardFunction();
|
253
|
+
localStorage.setItem("keyboard", sco_keyboards);
|
254
|
+
document.getElementById('keyboard-tips')?.classList.remove('show');
|
322
255
|
},
|
256
|
+
/**
|
257
|
+
* initConsoleState
|
258
|
+
* @description 初始化控制台状态
|
259
|
+
*/
|
260
|
+
initConsoleState: () => document.documentElement.classList.contains("hide-aside") ? document.querySelector("#consoleHideAside").classList.add("on") : document.querySelector("#consoleHideAside").classList.remove("on"),
|
261
|
+
/**
|
262
|
+
* changeSayHelloText
|
263
|
+
* @description 更改打招呼文本
|
264
|
+
*/
|
323
265
|
changeSayHelloText: function () {
|
324
266
|
const greetings = GLOBAL_CONFIG.aside.sayhello2;
|
325
267
|
const greetingElement = document.getElementById("author-info__sayhi");
|
326
|
-
let randomGreeting
|
327
|
-
|
268
|
+
let randomGreeting;
|
269
|
+
do {
|
328
270
|
randomGreeting = greetings[Math.floor(Math.random() * greetings.length)];
|
329
|
-
}
|
271
|
+
} while (randomGreeting === lastSayHello);
|
330
272
|
greetingElement.textContent = randomGreeting;
|
331
273
|
lastSayHello = randomGreeting;
|
332
274
|
},
|
275
|
+
/**
|
276
|
+
* switchDarkMode
|
277
|
+
* @description 切换显示模式
|
278
|
+
*/
|
333
279
|
switchDarkMode: function () {
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
} else {
|
342
|
-
document.documentElement.setAttribute('data-theme', 'light')
|
343
|
-
utils.saveToLocal.set('theme', 'light', 0.02);
|
344
|
-
utils.snackbarShow(GLOBAL_CONFIG.lang.theme.light, false, 2000)
|
345
|
-
is_rm && rm.mode(false)
|
346
|
-
}
|
347
|
-
handleThemeChange(nowMode)
|
280
|
+
const isDarkMode = document.documentElement.getAttribute('data-theme') === 'dark';
|
281
|
+
const newMode = isDarkMode ? 'light' : 'dark';
|
282
|
+
document.documentElement.setAttribute('data-theme', newMode);
|
283
|
+
utils.saveToLocal.set('theme', newMode, 0.02);
|
284
|
+
utils.snackbarShow(GLOBAL_CONFIG.lang.theme[newMode], false, 2000);
|
285
|
+
if (is_rm) rm.mode(!isDarkMode);
|
286
|
+
handleThemeChange(newMode);
|
348
287
|
},
|
288
|
+
/**
|
289
|
+
* hideTodayCard
|
290
|
+
* @description 隐藏今日卡片
|
291
|
+
*/
|
349
292
|
hideTodayCard: () => document.getElementById('todayCard').classList.add('hide'),
|
293
|
+
/**
|
294
|
+
* toTop
|
295
|
+
* @description 返回顶部
|
296
|
+
*/
|
350
297
|
toTop: () => utils.scrollToDest(0),
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
298
|
+
/**
|
299
|
+
* showConsole
|
300
|
+
* @description 显示控制台
|
301
|
+
*/
|
302
|
+
showConsole: () => document.getElementById('console')?.classList.toggle('show', true),
|
303
|
+
/**
|
304
|
+
* hideConsole
|
305
|
+
* @description 隐藏控制台
|
306
|
+
*/
|
307
|
+
hideConsole: () => document.getElementById('console')?.classList.remove('show'),
|
308
|
+
/**
|
309
|
+
* refreshWaterFall
|
310
|
+
* @description 刷新瀑布流
|
311
|
+
*/
|
361
312
|
refreshWaterFall: function () {
|
362
|
-
const
|
363
|
-
|
364
|
-
|
365
|
-
|
313
|
+
const observer = new IntersectionObserver((entries) => {
|
314
|
+
entries.forEach(entry => {
|
315
|
+
if (entry.isIntersecting) {
|
316
|
+
waterfall(entry.target) || entry.target.classList.add('show');
|
317
|
+
}
|
318
|
+
});
|
319
|
+
});
|
320
|
+
document.querySelectorAll('.waterfall').forEach(el => observer.observe(el));
|
366
321
|
},
|
322
|
+
/**
|
323
|
+
* addRuntime
|
324
|
+
* @description 添加运行时间
|
325
|
+
*/
|
367
326
|
addRuntime: function () {
|
368
327
|
let el = document.getElementById('runtimeshow')
|
369
328
|
el && GLOBAL_CONFIG.runtime && (el.innerText = utils.timeDiff(new Date(GLOBAL_CONFIG.runtime), new Date()) + GLOBAL_CONFIG.lang.time.day)
|
370
329
|
},
|
330
|
+
/**
|
331
|
+
* toTalk
|
332
|
+
* @description 回复评论
|
333
|
+
* @param txt
|
334
|
+
*/
|
371
335
|
toTalk: function (txt) {
|
372
|
-
const inputs = ["#wl-edit", ".el-textarea__inner", "#veditor", ".atk-textarea"]
|
373
|
-
|
374
|
-
|
375
|
-
if (el
|
376
|
-
el.dispatchEvent(new Event('input', {
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
el.
|
381
|
-
utils.scrollToDest(utils.getEleTop(document.getElementById('post-comment')), 300)
|
382
|
-
el.focus()
|
383
|
-
el.setSelectionRange(-1, -1)
|
336
|
+
const inputs = ["#wl-edit", ".el-textarea__inner", "#veditor", ".atk-textarea"];
|
337
|
+
inputs.forEach(selector => {
|
338
|
+
const el = document.querySelector(selector);
|
339
|
+
if (el) {
|
340
|
+
el.dispatchEvent(new Event('input', {bubble: true, cancelable: true}));
|
341
|
+
el.value = '> ' + txt.replace(/\n/g, '\n> ') + '\n\n';
|
342
|
+
utils.scrollToDest(utils.getEleTop(document.getElementById('post-comment')), 300);
|
343
|
+
el.focus();
|
344
|
+
el.setSelectionRange(-1, -1);
|
384
345
|
}
|
385
|
-
}
|
386
|
-
utils.snackbarShow(GLOBAL_CONFIG.lang.totalk,
|
346
|
+
});
|
347
|
+
utils.snackbarShow(GLOBAL_CONFIG.lang.totalk, false, 2000);
|
387
348
|
},
|
349
|
+
/**
|
350
|
+
* initbbtalk
|
351
|
+
* @description 初始化 bbtalk
|
352
|
+
*/
|
388
353
|
initbbtalk: function () {
|
389
|
-
|
390
|
-
|
354
|
+
const bberTalkElement = document.querySelector('#bber-talk');
|
355
|
+
if (bberTalkElement) {
|
356
|
+
new Swiper('.swiper-container', {
|
391
357
|
direction: 'vertical',
|
392
358
|
loop: true,
|
393
359
|
autoplay: {
|
@@ -397,264 +363,192 @@ let sco = {
|
|
397
363
|
});
|
398
364
|
}
|
399
365
|
},
|
366
|
+
/**
|
367
|
+
* addPhotoFigcaption
|
368
|
+
* @description 添加图片标题
|
369
|
+
*/
|
400
370
|
addPhotoFigcaption: function () {
|
401
|
-
|
402
|
-
images.forEach((image) => {
|
403
|
-
const imageParent = image.parentNode;
|
371
|
+
document.querySelectorAll('#article-container img').forEach(image => {
|
404
372
|
const captionText = image.getAttribute('alt');
|
405
|
-
|
406
|
-
if (captionText) {
|
407
|
-
const captionElement = document.createElement('div');
|
408
|
-
captionElement.className = 'img-alt is-center';
|
409
|
-
captionElement.textContent = captionText;
|
410
|
-
|
411
|
-
imageParent.insertBefore(captionElement, image.nextSibling);
|
412
|
-
}
|
373
|
+
captionText && image.insertAdjacentHTML('afterend', `<div class="img-alt is-center">${captionText}</div>`);
|
413
374
|
});
|
414
375
|
},
|
376
|
+
/**
|
377
|
+
* scrollToComment
|
378
|
+
* @description 滚动到评论
|
379
|
+
*/
|
415
380
|
scrollToComment: function () {
|
416
381
|
utils.scrollToDest(utils.getEleTop(document.getElementById('post-comment')), 300)
|
417
382
|
},
|
383
|
+
/**
|
384
|
+
* setTimeState
|
385
|
+
* @description 设置时间状态
|
386
|
+
*/
|
418
387
|
setTimeState: function () {
|
419
388
|
const el = document.getElementById('author-info__sayhi');
|
420
389
|
if (el) {
|
421
|
-
const
|
422
|
-
const hours = timeNow.getHours();
|
390
|
+
const hours = new Date().getHours();
|
423
391
|
const lang = GLOBAL_CONFIG.aside.sayhello;
|
424
|
-
const greetings = [
|
425
|
-
start: 0,
|
426
|
-
end:
|
427
|
-
text: lang.
|
428
|
-
|
429
|
-
{
|
430
|
-
start: 6,
|
431
|
-
end: 10,
|
432
|
-
text: lang.morning
|
433
|
-
},
|
434
|
-
{
|
435
|
-
start: 11,
|
436
|
-
end: 14,
|
437
|
-
text: lang.noon
|
438
|
-
},
|
439
|
-
{
|
440
|
-
start: 15,
|
441
|
-
end: 18,
|
442
|
-
text: lang.afternoon
|
443
|
-
},
|
444
|
-
{
|
445
|
-
start: 19,
|
446
|
-
end: 24,
|
447
|
-
text: lang.night
|
448
|
-
},
|
392
|
+
const greetings = [
|
393
|
+
{start: 0, end: 5, text: lang.goodnight},
|
394
|
+
{start: 6, end: 10, text: lang.morning},
|
395
|
+
{start: 11, end: 14, text: lang.noon},
|
396
|
+
{start: 15, end: 18, text: lang.afternoon},
|
397
|
+
{start: 19, end: 24, text: lang.night},
|
449
398
|
];
|
450
|
-
|
451
|
-
|
452
|
-
el.innerText = greeting.text;
|
453
|
-
break;
|
454
|
-
}
|
455
|
-
}
|
399
|
+
const greeting = greetings.find(g => hours >= g.start && hours <= g.end);
|
400
|
+
el.innerText = greeting.text;
|
456
401
|
}
|
457
402
|
},
|
403
|
+
/**
|
404
|
+
* tagPageActive
|
405
|
+
* @description 标签页当前标签高亮
|
406
|
+
*/
|
458
407
|
tagPageActive: function () {
|
459
|
-
const
|
460
|
-
const decodedPath = decodeURIComponent(currentPath);
|
461
|
-
|
408
|
+
const decodedPath = decodeURIComponent(window.location.pathname);
|
462
409
|
const isTagPage = /\/tags\/.*?\//.test(decodedPath);
|
463
410
|
if (isTagPage) {
|
464
411
|
const tag = decodedPath.split("/").slice(-2, -1)[0];
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
const allLinks = document.querySelectorAll("a");
|
469
|
-
allLinks.forEach(link => {
|
412
|
+
const tagElement = document.getElementById(tag);
|
413
|
+
if (tagElement) {
|
414
|
+
document.querySelectorAll("a.select").forEach(link => {
|
470
415
|
link.classList.remove("select");
|
471
416
|
});
|
472
|
-
|
473
|
-
const tagElement = document.getElementById(tag);
|
474
|
-
if (tagElement) {
|
475
|
-
tagElement.classList.add("select");
|
476
|
-
}
|
417
|
+
tagElement.classList.add("select");
|
477
418
|
}
|
478
419
|
}
|
479
420
|
},
|
421
|
+
/**
|
422
|
+
* categoriesBarActive
|
423
|
+
* @description 分类栏当前分类高亮
|
424
|
+
*/
|
480
425
|
categoriesBarActive: function () {
|
481
426
|
const categoryBar = document.querySelector("#category-bar");
|
482
|
-
const currentPath = window.location.pathname;
|
483
|
-
const
|
484
|
-
|
427
|
+
const currentPath = decodeURIComponent(window.location.pathname);
|
428
|
+
const isHomePage = currentPath === "/";
|
485
429
|
if (categoryBar) {
|
486
|
-
const
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
if (
|
491
|
-
|
492
|
-
homeItem.classList.add("select");
|
493
|
-
} else {
|
494
|
-
if (/\/categories\/.*?\//.test(decodedPath)) {
|
495
|
-
let category = decodedPath.split("/").slice(-2, -1)[0];
|
496
|
-
category = category.charAt(0).toUpperCase() + category.slice(1);
|
497
|
-
const categoryItem = document.getElementById(category);
|
498
|
-
if (categoryItem) {
|
499
|
-
categoryItem.classList.add("select");
|
500
|
-
}
|
501
|
-
}
|
430
|
+
const categoryItems = categoryBar.querySelectorAll(".category-bar-item");
|
431
|
+
categoryItems.forEach(item => item.classList.remove("select"));
|
432
|
+
const activeItemId = isHomePage ? "category-bar-home" : currentPath.split("/").slice(-2, -1)[0];
|
433
|
+
const activeItem = document.getElementById(activeItemId);
|
434
|
+
if (activeItem) {
|
435
|
+
activeItem.classList.add("select");
|
502
436
|
}
|
503
437
|
}
|
504
438
|
},
|
439
|
+
/**
|
440
|
+
* scrollCategoryBarToRight
|
441
|
+
* @description 滚动分类栏到右侧
|
442
|
+
*/
|
505
443
|
scrollCategoryBarToRight: function () {
|
506
|
-
|
507
|
-
|
508
|
-
let nextElement = document.getElementById("category-bar-next");
|
509
|
-
let scrollBarWidth = scrollBar.clientWidth;
|
444
|
+
const scrollBar = document.getElementById("category-bar-items");
|
445
|
+
const nextElement = document.getElementById("category-bar-next");
|
510
446
|
if (scrollBar) {
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
behavior: "smooth"
|
515
|
-
}
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
clearTimeout(timeoutId);
|
524
|
-
timeoutId = setTimeout(function () {
|
525
|
-
if (scrollBar.scrollLeft + scrollBar.clientWidth >= scrollBar.scrollWidth - 8) {
|
526
|
-
nextElement.style.transform = "rotate(180deg)";
|
527
|
-
} else {
|
528
|
-
nextElement.style.transform = "";
|
529
|
-
}
|
530
|
-
scrollBar.removeEventListener("scroll", onScroll);
|
447
|
+
const isScrollBarAtEnd = () => scrollBar.scrollLeft + scrollBar.clientWidth >= scrollBar.scrollWidth - 8;
|
448
|
+
const scroll = () => {
|
449
|
+
if (isScrollBarAtEnd()) {
|
450
|
+
scrollBar.scroll({left: 0, behavior: "smooth"});
|
451
|
+
} else {
|
452
|
+
scrollBar.scrollBy({left: scrollBar.clientWidth, behavior: "smooth"});
|
453
|
+
}
|
454
|
+
};
|
455
|
+
scrollBar.addEventListener("scroll", () => {
|
456
|
+
clearTimeout(this.timeoutId);
|
457
|
+
this.timeoutId = setTimeout(() => {
|
458
|
+
nextElement.style.transform = isScrollBarAtEnd() ? "rotate(180deg)" : "";
|
531
459
|
}, 150);
|
532
460
|
});
|
461
|
+
scroll();
|
533
462
|
}
|
534
463
|
},
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
moreTagsButton.parentNode.removeChild(moreTagsButton);
|
543
|
-
}
|
464
|
+
/**
|
465
|
+
* openAllTags
|
466
|
+
* @description 展开所有标签
|
467
|
+
*/
|
468
|
+
openAllTags: () => {
|
469
|
+
document.querySelectorAll(".card-allinfo .card-tag-cloud").forEach(tagCloudElement => tagCloudElement.classList.add("all-tags"));
|
470
|
+
document.getElementById("more-tags-btn")?.remove();
|
544
471
|
},
|
472
|
+
/**
|
473
|
+
* listenToPageInputPress
|
474
|
+
* @description 监听页码输入
|
475
|
+
*/
|
545
476
|
listenToPageInputPress: function () {
|
546
477
|
const pageText = document.getElementById("toPageText");
|
547
|
-
const pageButton = document.getElementById("toPageButton");
|
548
|
-
|
549
478
|
if (!pageText) return;
|
550
|
-
|
479
|
+
const pageButton = document.getElementById("toPageButton");
|
551
480
|
const pageNumbers = document.querySelectorAll(".page-number");
|
552
481
|
const lastPageNumber = +pageNumbers[pageNumbers.length - 1].textContent;
|
553
|
-
|
554
|
-
if (lastPageNumber === 1) {
|
555
|
-
const toPageGroup = document.querySelector(".toPageGroup");
|
556
|
-
if (toPageGroup) toPageGroup.remove();
|
557
|
-
}
|
558
|
-
|
482
|
+
if (!pageText || lastPageNumber === 1) return;
|
559
483
|
pageText.addEventListener("keydown", (event) => {
|
560
484
|
if (event.keyCode === 13) {
|
561
485
|
sco.toPage();
|
562
486
|
pjax.loadUrl(pageButton.href);
|
563
487
|
}
|
564
488
|
});
|
565
|
-
|
566
489
|
pageText.addEventListener("input", () => {
|
567
|
-
|
568
|
-
pageButton.classList.remove("haveValue");
|
569
|
-
} else {
|
570
|
-
pageButton.classList.add("haveValue");
|
571
|
-
}
|
572
|
-
|
573
|
-
const pageNumbers = document.querySelectorAll(".page-number");
|
574
|
-
const lastPageNumber = +pageNumbers[pageNumbers.length - 1].textContent;
|
575
|
-
|
490
|
+
pageButton.classList.toggle("haveValue", pageText.value !== "" && pageText.value !== "0");
|
576
491
|
if (+pageText.value > lastPageNumber) {
|
577
492
|
pageText.value = lastPageNumber;
|
578
493
|
}
|
579
494
|
});
|
580
495
|
},
|
496
|
+
/**
|
497
|
+
* addNavBackgroundInit
|
498
|
+
* @description 添加导航背景初始化
|
499
|
+
*/
|
581
500
|
addNavBackgroundInit: function () {
|
582
|
-
|
583
|
-
|
584
|
-
document.body && (e = document.body.scrollTop),
|
585
|
-
document.documentElement && (t = document.documentElement.scrollTop),
|
586
|
-
0 !== (e - t > 0 ? e : t) && (document.getElementById("page-header").classList.add("nav-fixed"), document.getElementById("page-header").classList.add("nav-visible"))
|
501
|
+
const scrollTop = document.documentElement.scrollTop;
|
502
|
+
(scrollTop !== 0) && document.getElementById("page-header").classList.add("nav-fixed", "nav-visible");
|
587
503
|
const cookiesWindow = document.getElementById("cookies-window");
|
588
|
-
|
589
|
-
cookiesWindow.style.display = 'none';
|
590
|
-
}
|
504
|
+
cookiesWindow && (cookiesWindow.style.display = 'none')
|
591
505
|
},
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
const $
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
const
|
605
|
-
|
606
|
-
|
607
|
-
else t = blogNameWidth + menusWidth + searchWidth > $nav?.offsetWidth - 120
|
608
|
-
|
609
|
-
if (t) {
|
610
|
-
$nav?.classList.add('hide-menu')
|
506
|
+
/**
|
507
|
+
* initAdjust
|
508
|
+
* @description 初始化调整
|
509
|
+
*/
|
510
|
+
initAdjust: function () {
|
511
|
+
const $blogName = document.getElementById('site-name');
|
512
|
+
const $menusEle = document.querySelector('#menus .menus_items');
|
513
|
+
const $searchEle = document.querySelector('#search-button');
|
514
|
+
const $nav = document.getElementById('nav');
|
515
|
+
const blogNameWidth = $blogName && $blogName.offsetWidth;
|
516
|
+
const menusWidth = $menusEle && $menusEle.offsetWidth;
|
517
|
+
const searchWidth = $searchEle && $searchEle.offsetWidth;
|
518
|
+
const shouldHideMenu = window.innerWidth < 768 || blogNameWidth + menusWidth + searchWidth > $nav?.offsetWidth - 120;
|
519
|
+
if (shouldHideMenu) {
|
520
|
+
$nav?.classList.add('hide-menu');
|
611
521
|
} else {
|
612
|
-
$nav?.classList.remove('hide-menu')
|
522
|
+
$nav?.classList.remove('hide-menu');
|
613
523
|
}
|
614
|
-
|
615
|
-
document.getElementById('nav')?.classList.add('show')
|
524
|
+
$nav?.classList.add('show');
|
616
525
|
},
|
526
|
+
/**
|
527
|
+
* toPage
|
528
|
+
* @description 跳转到指定页
|
529
|
+
*/
|
617
530
|
toPage: function () {
|
618
531
|
const pageNumbers = document.querySelectorAll(".page-number");
|
619
532
|
const maxPageNumber = parseInt(pageNumbers[pageNumbers.length - 1].innerHTML);
|
620
533
|
const inputElement = document.getElementById("toPageText");
|
621
534
|
const inputPageNumber = parseInt(inputElement.value);
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
let targetPageUrl;
|
626
|
-
|
627
|
-
if (inputPageNumber === 1) {
|
628
|
-
targetPageUrl = currentPageUrl;
|
629
|
-
} else {
|
630
|
-
targetPageUrl = currentPageUrl + (currentPageUrl.endsWith("/") ? "" : "/") + "page/" + inputPageNumber + "/";
|
631
|
-
}
|
632
|
-
|
633
|
-
document.getElementById("toPageButton").href = targetPageUrl;
|
634
|
-
}
|
535
|
+
document.getElementById("toPageButton").href = (!isNaN(inputPageNumber) && inputPageNumber <= maxPageNumber && inputPageNumber > 1)
|
536
|
+
? window.location.href.replace(/\/page\/\d+\/$/, "/") + "page/" + inputPageNumber + "/"
|
537
|
+
: '/';
|
635
538
|
},
|
539
|
+
/**
|
540
|
+
* owobig
|
541
|
+
* @description owo 大图
|
542
|
+
* @param owoSelector
|
543
|
+
*/
|
636
544
|
owoBig(owoSelector) {
|
637
|
-
|
638
545
|
let owoBig = document.getElementById('owo-big');
|
639
546
|
if (!owoBig) {
|
640
547
|
owoBig = document.createElement('div');
|
641
548
|
owoBig.id = 'owo-big';
|
642
549
|
document.body.appendChild(owoBig);
|
643
550
|
}
|
644
|
-
|
645
|
-
const debounce = (func, wait) => {
|
646
|
-
let timeout;
|
647
|
-
return function (...args) {
|
648
|
-
const later = () => {
|
649
|
-
clearTimeout(timeout);
|
650
|
-
func(...args);
|
651
|
-
};
|
652
|
-
clearTimeout(timeout);
|
653
|
-
timeout = setTimeout(later, wait);
|
654
|
-
};
|
655
|
-
};
|
656
|
-
|
657
|
-
const showOwoBig = (event) => {
|
551
|
+
const showOwoBig = event => {
|
658
552
|
const target = event.target;
|
659
553
|
const owoItem = target.closest(owoSelector.item);
|
660
554
|
if (owoItem && target.closest(owoSelector.body)) {
|
@@ -666,22 +560,24 @@ let sco = {
|
|
666
560
|
}
|
667
561
|
}
|
668
562
|
};
|
669
|
-
|
670
|
-
const hideOwoBig = (event) => {
|
563
|
+
const hideOwoBig = event => {
|
671
564
|
if (event.target.closest(owoSelector.item) && event.target.closest(owoSelector.body)) {
|
672
565
|
owoBig.style.display = 'none';
|
673
566
|
}
|
674
567
|
};
|
675
|
-
|
676
|
-
function positionOwoBig(owoItem) {
|
568
|
+
const positionOwoBig = owoItem => {
|
677
569
|
const itemRect = owoItem.getBoundingClientRect();
|
678
570
|
owoBig.style.left = `${itemRect.left - (owoBig.offsetWidth / 4)}px`;
|
679
571
|
owoBig.style.top = `${itemRect.top}px`;
|
680
572
|
}
|
681
|
-
|
682
|
-
document.addEventListener('mouseover', debounce(showOwoBig, 100));
|
573
|
+
document.addEventListener('mouseover', showOwoBig);
|
683
574
|
document.addEventListener('mouseout', hideOwoBig);
|
684
575
|
},
|
576
|
+
/**
|
577
|
+
* changeTimeFormat
|
578
|
+
* @description 更改时间格式
|
579
|
+
* @param selector
|
580
|
+
*/
|
685
581
|
changeTimeFormat(selector) {
|
686
582
|
selector.forEach(item => {
|
687
583
|
const timeVal = item.getAttribute('datetime')
|
@@ -689,6 +585,10 @@ let sco = {
|
|
689
585
|
item.style.display = 'inline'
|
690
586
|
})
|
691
587
|
},
|
588
|
+
/**
|
589
|
+
* switchComments
|
590
|
+
* @description 切换评论
|
591
|
+
*/
|
692
592
|
switchComments() {
|
693
593
|
const switchBtn = document.getElementById('switch-btn')
|
694
594
|
if (!switchBtn) return
|
@@ -705,35 +605,23 @@ let sco = {
|
|
705
605
|
},
|
706
606
|
}
|
707
607
|
|
608
|
+
/**
|
609
|
+
* addHighlight
|
610
|
+
* @description 添加代码高亮
|
611
|
+
*/
|
708
612
|
const addHighlight = () => {
|
709
613
|
const highlight = GLOBAL_CONFIG.highlight;
|
710
614
|
if (!highlight) return;
|
711
|
-
|
712
615
|
const {copy, expand, limit, syntax} = highlight;
|
713
616
|
const $isPrismjs = syntax === 'prismjs';
|
714
617
|
const $isShowTool = highlight.enable || copy || expand || limit;
|
715
618
|
const expandClass = !expand === true ? 'closed' : ''
|
716
619
|
const $syntaxHighlight = syntax === 'highlight.js' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]')
|
717
|
-
|
718
620
|
if (!(($isShowTool || limit) && $syntaxHighlight.length)) return
|
719
|
-
|
720
621
|
const copyEle = copy ? `<i class="solitude st-copy-fill copy-button"></i>` : '<i></i>';
|
721
622
|
const expandEle = `<i class="solitude st-arrow-down expand"></i>`;
|
722
623
|
const limitEle = limit ? `<i class="solitude st-show-line"></i>` : '<i></i>';
|
723
|
-
|
724
|
-
const alertInfo = (ele, text) => {
|
725
|
-
utils.snackbarShow(text, false, 2000);
|
726
|
-
}
|
727
|
-
|
728
|
-
const copyCode = (e) => {
|
729
|
-
if (document.queryCommandSupported && document.queryCommandSupported('copy')) {
|
730
|
-
document.execCommand('copy')
|
731
|
-
alertInfo(e, GLOBAL_CONFIG.lang.copy.success)
|
732
|
-
} else {
|
733
|
-
alertInfo(e, GLOBAL_CONFIG.lang.copy.error)
|
734
|
-
}
|
735
|
-
}
|
736
|
-
|
624
|
+
const alertInfo = (ele, text) => utils.snackbarShow(text, false, 2000)
|
737
625
|
const copyFn = (e) => {
|
738
626
|
const $buttonParent = e.parentNode
|
739
627
|
$buttonParent.classList.add('copy-true')
|
@@ -743,28 +631,22 @@ const addHighlight = () => {
|
|
743
631
|
range.selectNodeContents($buttonParent.querySelectorAll(`${preCodeSelector}`)[0])
|
744
632
|
selection.removeAllRanges()
|
745
633
|
selection.addRange(range)
|
746
|
-
|
634
|
+
document.execCommand('copy')
|
635
|
+
alertInfo(e.lastChild, GLOBAL_CONFIG.lang.copy.success)
|
747
636
|
selection.removeAllRanges()
|
748
637
|
$buttonParent.classList.remove('copy-true')
|
749
638
|
}
|
750
|
-
|
751
|
-
const expandClose = (e) => {
|
752
|
-
e.classList.toggle('closed')
|
753
|
-
}
|
754
|
-
|
639
|
+
const expandClose = (e) => e.classList.toggle('closed')
|
755
640
|
const shrinkEle = function () {
|
756
641
|
this.classList.toggle('expand-done')
|
757
642
|
}
|
758
|
-
|
759
643
|
const ToolsFn = function (e) {
|
760
644
|
const $target = e.target.classList
|
761
645
|
if ($target.contains('expand')) expandClose(this)
|
762
646
|
else if ($target.contains('copy-button')) copyFn(this)
|
763
647
|
}
|
764
|
-
|
765
648
|
const createEle = (lang, item, service) => {
|
766
649
|
const fragment = document.createDocumentFragment()
|
767
|
-
|
768
650
|
if ($isShowTool) {
|
769
651
|
const hlTools = document.createElement('div')
|
770
652
|
hlTools.className = `highlight-tools ${expandClass}`
|
@@ -772,23 +654,19 @@ const addHighlight = () => {
|
|
772
654
|
utils.addEventListenerPjax(hlTools, 'click', ToolsFn)
|
773
655
|
fragment.appendChild(hlTools)
|
774
656
|
}
|
775
|
-
|
776
657
|
if (limit && item.offsetHeight > limit + 30) {
|
777
|
-
|
778
658
|
const ele = document.createElement('div')
|
779
659
|
ele.className = 'code-expand-btn'
|
780
660
|
ele.innerHTML = limitEle
|
781
661
|
utils.addEventListenerPjax(ele, 'click', shrinkEle)
|
782
662
|
fragment.appendChild(ele)
|
783
663
|
}
|
784
|
-
|
785
664
|
if (service === 'hl') {
|
786
665
|
item.insertBefore(fragment, item.firstChild)
|
787
666
|
} else {
|
788
667
|
item.parentNode.insertBefore(fragment, item)
|
789
668
|
}
|
790
669
|
}
|
791
|
-
|
792
670
|
if ($isPrismjs) {
|
793
671
|
$syntaxHighlight.forEach(item => {
|
794
672
|
const langName = item.getAttribute('data-language') || 'Code'
|
@@ -808,36 +686,80 @@ const addHighlight = () => {
|
|
808
686
|
}
|
809
687
|
}
|
810
688
|
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
if (
|
819
|
-
|
820
|
-
|
821
|
-
if (e.clipboardData) {
|
822
|
-
return e.clipboardData.setData('text', text)
|
823
|
-
} else {
|
824
|
-
return window.clipboardData.setData('text', text)
|
689
|
+
/**
|
690
|
+
* toc
|
691
|
+
* @description 目录
|
692
|
+
*/
|
693
|
+
class toc {
|
694
|
+
static init() {
|
695
|
+
const tocContainer = document.getElementById('card-toc')
|
696
|
+
if (!tocContainer || !tocContainer.querySelector('.toc a')) {
|
697
|
+
tocContainer.style.display = 'none'
|
698
|
+
return
|
825
699
|
}
|
700
|
+
const el = document.querySelectorAll('.toc a')
|
701
|
+
el.forEach((e) => {
|
702
|
+
e.addEventListener('click', (event) => {
|
703
|
+
event.preventDefault()
|
704
|
+
utils.scrollToDest(utils.getEleTop(document.getElementById(decodeURI((event.target.className === 'toc-text' ? event.target.parentNode.hash : event.target.hash).replace('#', '')))), 300)
|
705
|
+
})
|
706
|
+
})
|
707
|
+
this.active(el)
|
826
708
|
}
|
827
|
-
document.body.addEventListener('copy', handleCopy)
|
828
|
-
}
|
829
709
|
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
710
|
+
static active(toc) {
|
711
|
+
const $article = document.getElementById('article-container')
|
712
|
+
const $tocContent = document.getElementById('toc-content')
|
713
|
+
const list = $article.querySelectorAll('h1,h2,h3,h4,h5,h6')
|
714
|
+
let detectItem = ''
|
715
|
+
|
716
|
+
function autoScroll(el) {
|
717
|
+
const activePosition = el.getBoundingClientRect().top
|
718
|
+
const sidebarScrollTop = $tocContent.scrollTop
|
719
|
+
if (activePosition > (document.documentElement.clientHeight - 100)) {
|
720
|
+
$tocContent.scrollTop = sidebarScrollTop + 150
|
721
|
+
}
|
722
|
+
if (activePosition < 100) {
|
723
|
+
$tocContent.scrollTop = sidebarScrollTop - 150
|
724
|
+
}
|
725
|
+
}
|
726
|
+
|
727
|
+
function findHeadPosition(top) {
|
728
|
+
if (top === 0) return false
|
729
|
+
let currentIndex = ''
|
730
|
+
list.forEach(function (ele, index) {
|
731
|
+
if (top > utils.getEleTop(ele) - 80) {
|
732
|
+
currentIndex = index
|
733
|
+
}
|
734
|
+
})
|
735
|
+
if (detectItem === currentIndex) return
|
736
|
+
detectItem = currentIndex
|
737
|
+
document.querySelectorAll('.toc .active').forEach((i) => {
|
738
|
+
i.classList.remove('active')
|
739
|
+
})
|
740
|
+
const activeitem = toc[detectItem]
|
741
|
+
if (activeitem) {
|
742
|
+
let parent = toc[detectItem].parentNode
|
743
|
+
activeitem.classList.add('active')
|
744
|
+
autoScroll(activeitem)
|
745
|
+
for (; !parent.matches('.toc'); parent = parent.parentNode) {
|
746
|
+
if (parent.matches('li')) parent.classList.add('active')
|
747
|
+
}
|
748
|
+
}
|
837
749
|
}
|
750
|
+
|
751
|
+
window.tocScrollFn = utils.throttle(function () {
|
752
|
+
const currentTop = window.scrollY || document.documentElement.scrollTop
|
753
|
+
findHeadPosition(currentTop)
|
754
|
+
}, 100)
|
755
|
+
window.addEventListener('scroll', tocScrollFn)
|
838
756
|
}
|
839
757
|
}
|
840
758
|
|
759
|
+
/**
|
760
|
+
* tabs
|
761
|
+
* @description 外挂标签tabs
|
762
|
+
*/
|
841
763
|
class tabs {
|
842
764
|
static init() {
|
843
765
|
this.clickFnOfTabs()
|
@@ -845,20 +767,17 @@ class tabs {
|
|
845
767
|
}
|
846
768
|
|
847
769
|
static clickFnOfTabs() {
|
848
|
-
document.querySelectorAll('#article-container .tab > button').forEach(
|
849
|
-
item.addEventListener('click',
|
850
|
-
const
|
851
|
-
const $tabItem = that.parentNode
|
770
|
+
document.querySelectorAll('#article-container .tab > button').forEach(item => {
|
771
|
+
item.addEventListener('click', e => {
|
772
|
+
const $tabItem = e.target.parentNode
|
852
773
|
if (!$tabItem.classList.contains('active')) {
|
853
774
|
const $tabContent = $tabItem.parentNode.nextElementSibling
|
854
|
-
const $siblings =
|
775
|
+
const $siblings = $tabItem.parentNode.querySelector('.active')
|
855
776
|
$siblings && $siblings.classList.remove('active')
|
856
777
|
$tabItem.classList.add('active')
|
857
|
-
const tabId =
|
858
|
-
|
859
|
-
|
860
|
-
if (item.id === tabId) item.classList.add('active')
|
861
|
-
else item.classList.remove('active')
|
778
|
+
const tabId = e.target.getAttribute('data-href').replace('#', '')
|
779
|
+
Array.from($tabContent.children).forEach(item => {
|
780
|
+
item.id === tabId ? item.classList.add('active') : item.classList.remove('active')
|
862
781
|
})
|
863
782
|
}
|
864
783
|
})
|
@@ -866,58 +785,46 @@ class tabs {
|
|
866
785
|
}
|
867
786
|
|
868
787
|
static backToTop() {
|
869
|
-
document.querySelectorAll('#article-container .tabs .tab-to-top').forEach(
|
870
|
-
item.addEventListener('click',
|
871
|
-
utils.scrollToDest(utils.getEleTop(item.
|
872
|
-
|
788
|
+
document.querySelectorAll('#article-container .tabs .tab-to-top').forEach(item => {
|
789
|
+
item.addEventListener('click', () => {
|
790
|
+
utils.scrollToDest(utils.getEleTop(item.closest('.tabs')), 300)
|
873
791
|
})
|
874
792
|
})
|
875
793
|
}
|
876
794
|
}
|
877
795
|
|
796
|
+
// 页面刷新
|
878
797
|
window.refreshFn = () => {
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
798
|
+
const {is_home, is_page, page, is_post} = PAGE_CONFIG;
|
799
|
+
const {runtime, lazyload, lightbox, randomlink, covercolor, post_ai} = GLOBAL_CONFIG;
|
800
|
+
const timeSelector = is_home || is_page ? '#recent-posts time, .webinfo-item time' : '#post-meta time';
|
801
|
+
document.body.setAttribute('data-type', page);
|
802
|
+
sco.changeTimeFormat(document.querySelectorAll(timeSelector));
|
803
|
+
runtime && sco.addRuntime();
|
804
|
+
[scrollFn, sidebarFn, sco.hideCookie, sco.addPhotoFigcaption, sco.setTimeState, sco.tagPageActive, sco.categoriesBarActive, sco.listenToPageInputPress, sco.addNavBackgroundInit, sco.refreshWaterFall].forEach(fn => fn());
|
805
|
+
lazyload.enable && utils.lazyloadImg();
|
806
|
+
lightbox && utils.lightbox(document.querySelectorAll("#article-container img:not(.flink-avatar,.gallery-group img)"));
|
807
|
+
randomlink && randomLinksList();
|
808
|
+
post_ai && is_post && efu_ai.init();
|
809
|
+
sco.switchComments();
|
810
|
+
initObserver();
|
811
|
+
if (is_home) showTodayCard();
|
812
|
+
if (is_post || is_page) {
|
813
|
+
addHighlight();
|
814
|
+
tabs.init();
|
885
815
|
}
|
886
|
-
|
887
|
-
|
888
|
-
sco.hideCookie()
|
889
|
-
sco.addPhotoFigcaption()
|
890
|
-
sco.setTimeState()
|
891
|
-
sco.tagPageActive()
|
892
|
-
sco.categoriesBarActive()
|
893
|
-
sco.listenToPageInputPress()
|
894
|
-
sco.addNavBackgroundInit()
|
895
|
-
sco.refreshWaterFall()
|
896
|
-
GLOBAL_CONFIG.lazyload.enable && utils.lazyloadImg()
|
897
|
-
GLOBAL_CONFIG.lightbox && utils.lightbox(document.querySelectorAll("#article-container img:not(.flink-avatar,.gallery-group img)"))
|
898
|
-
GLOBAL_CONFIG.randomlink && randomLinksList()
|
899
|
-
PAGE_CONFIG.toc && toc.init();
|
900
|
-
(PAGE_CONFIG.is_post || PAGE_CONFIG.is_page) && ((addHighlight()) || tabs.init())
|
901
|
-
PAGE_CONFIG.is_home && showTodayCard()
|
902
|
-
GLOBAL_CONFIG.covercolor.enable && coverColor()
|
903
|
-
PAGE_CONFIG.page === "music" && scoMusic.init()
|
904
|
-
GLOBAL_CONFIG.post_ai && PAGE_CONFIG.is_post && efu_ai.init()
|
905
|
-
sco.switchComments()
|
816
|
+
if (covercolor.enable) coverColor();
|
817
|
+
if (PAGE_CONFIG.toc) toc.init();
|
906
818
|
}
|
907
|
-
|
908
|
-
document.addEventListener('DOMContentLoaded',
|
909
|
-
sco.initAdjust()
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
}
|
917
|
-
|
918
|
-
|
919
|
-
(123 === e.keyCode || (17 === e.ctrlKey && 16 === e.shiftKey && 67 === e.keyCode)) && utils.snackbarShow(GLOBAL_CONFIG.lang.f12, !1, 3e3);
|
920
|
-
(27 === e.keyCode) && sco.hideConsole();
|
921
|
-
}
|
922
|
-
|
923
|
-
document.addEventListener('copy', () => utils.snackbarShow(GLOBAL_CONFIG.lang.copy.success, false, 3e3))
|
819
|
+
// 页面加载完成后执行
|
820
|
+
document.addEventListener('DOMContentLoaded', () => {
|
821
|
+
[sco.initAdjust, addCopyright, sco.initConsoleState, window.refreshFn, asideStatus, () => window.onscroll = percent].forEach(fn => fn());
|
822
|
+
});
|
823
|
+
// 一些快捷键绑定
|
824
|
+
window.onkeydown = e => {
|
825
|
+
const {keyCode, ctrlKey, shiftKey} = e;
|
826
|
+
if (keyCode === 123 || (ctrlKey && shiftKey && keyCode === 67)) utils.snackbarShow(GLOBAL_CONFIG.lang.f12, false, 3000);
|
827
|
+
if (keyCode === 27) sco.hideConsole();
|
828
|
+
};
|
829
|
+
// 复制成功提示
|
830
|
+
document.addEventListener('copy', () => utils.snackbarShow(GLOBAL_CONFIG.lang.copy.success, false, 3000));
|