fixed 打包压缩静态文件
This commit is contained in:
1 parent
371ec8adca
commit
5efe7ded8e
25 files changed
+3212
-3186
No files matched your search
+1
-1
@@ -19,7 +19,7 @@ if ($LASTEXITCODE -ne 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "🚀 开始执行 Hugo 打包..." -ForegroundColor Cyan
|
Write-Host "🚀 开始执行 Hugo 打包..." -ForegroundColor Cyan
|
||||||
hugo
|
hugo --minify
|
||||||
|
|
||||||
if ($LASTEXITCODE -eq 0) {
|
if ($LASTEXITCODE -eq 0) {
|
||||||
Write-Host "🎉 打包成功!" -ForegroundColor Green
|
Write-Host "🎉 打包成功!" -ForegroundColor Green
|
||||||
|
|||||||
@@ -21,6 +21,16 @@ HasCJKLanguage = true
|
|||||||
style = 'dracula'
|
style = 'dracula'
|
||||||
noClasses = false
|
noClasses = false
|
||||||
|
|
||||||
|
[minify]
|
||||||
|
disableXML = true
|
||||||
|
[minify.tdewolff]
|
||||||
|
[minify.tdewolff.html]
|
||||||
|
keepConditionalComments = true
|
||||||
|
keepDefaultAttrVals = true
|
||||||
|
keepDocumentTags = true
|
||||||
|
keepEndTags = true
|
||||||
|
keepWhitespace = false
|
||||||
|
|
||||||
# 自定义文章固定链接:使用 日期 作为文件名(如 /20260117.html)
|
# 自定义文章固定链接:使用 日期 作为文件名(如 /20260117.html)
|
||||||
[permalinks]
|
[permalinks]
|
||||||
post = "/:year:month:day"
|
post = "/:year:month:day"
|
||||||
File renamed without changes.
+2863
-13
File diff suppressed because it is too large.
Load diff
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Vendored
File renamed without changes.
@@ -1 +1,279 @@
|
|||||||
console.log('This site was generated by Hugo.');
|
// 判断是否为移动端
|
||||||
|
function isMobile() {
|
||||||
|
if (window.navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {
|
||||||
|
return true; // 移动端
|
||||||
|
} else {
|
||||||
|
return false; // PC端
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文章图片灯箱
|
||||||
|
window.ViewImage && ViewImage.init('.post-content img');
|
||||||
|
|
||||||
|
// Pure JavaScript Back to Top (High Performance)
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
var backToTopButton = document.getElementById('back-to-top');
|
||||||
|
if (backToTopButton) {
|
||||||
|
var isVisible = false;
|
||||||
|
var ticking = false;
|
||||||
|
|
||||||
|
function update() {
|
||||||
|
if (window.scrollY > 300) {
|
||||||
|
if (!isVisible) {
|
||||||
|
backToTopButton.classList.add('show');
|
||||||
|
isVisible = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isVisible) {
|
||||||
|
backToTopButton.classList.remove('show');
|
||||||
|
isVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ticking = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', function() {
|
||||||
|
if (!ticking) {
|
||||||
|
window.requestAnimationFrame(update);
|
||||||
|
ticking = true;
|
||||||
|
}
|
||||||
|
}, { passive: true });
|
||||||
|
|
||||||
|
backToTopButton.addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: 'smooth'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// loader定时器
|
||||||
|
$(document).ready(function () {
|
||||||
|
setTimeout(function () {
|
||||||
|
$("#loader").addClass("hide");
|
||||||
|
}, 30000);
|
||||||
|
});
|
||||||
|
// 点击进入按钮
|
||||||
|
$("#closeloader").click(function () {
|
||||||
|
$("#loader").addClass("hide");
|
||||||
|
});
|
||||||
|
// nav栏样式调整
|
||||||
|
$('#libabys').first().attr("style", "margin-left: -5px");
|
||||||
|
|
||||||
|
$('#libabys').eq(1).attr("style", "margin-left: -5px");
|
||||||
|
// 友链列表版样式调整
|
||||||
|
$('.itp-index:odd').attr("style", "float: right;width:48%;");
|
||||||
|
|
||||||
|
//文章图片懒加载
|
||||||
|
lazyLoadInit({
|
||||||
|
// coverColor: "white",
|
||||||
|
// coverDiv: "<div style='display: flex; justify-content: center; align-items: center; height: 200px; color: #000000;'><span>优世界·一个记录生活点滴的小站</span></div>",
|
||||||
|
offsetBottom: 800,
|
||||||
|
offsetTopm: 800,
|
||||||
|
showTime: 1100
|
||||||
|
});
|
||||||
|
|
||||||
|
async function loadBarrager() {
|
||||||
|
try {
|
||||||
|
const commentsData = await initArtalkAndGetComments();
|
||||||
|
if (commentsData) {
|
||||||
|
await createBarragerFromArtalk(commentsData);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载弹幕时发生错误:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 异步初始化 Artalk 并获取评论数据
|
||||||
|
function initArtalkAndGetComments() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
Artalk.use((ctx) => {
|
||||||
|
ctx.on('list-loaded', () => {
|
||||||
|
console.log('评论列表加载完毕');
|
||||||
|
const commentsData = ctx.getComments();
|
||||||
|
if (commentsData) {
|
||||||
|
resolve(commentsData);
|
||||||
|
// console.log(commentsData);
|
||||||
|
} else {
|
||||||
|
reject('获取评论数据失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Artalk.init({
|
||||||
|
el: '#Comments', // 绑定元素的 Selector
|
||||||
|
server: 'https://artalk.usj.cc', // 后端地址
|
||||||
|
site: '优世界', // 你的站点名
|
||||||
|
flatMode: true,
|
||||||
|
emoticons: '/emotion/OwO.json'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 异步创建弹幕
|
||||||
|
async function createBarragerFromArtalk(commentsData) {
|
||||||
|
const looperTime = 1000; // 每条弹幕的发送间隔,单位毫秒
|
||||||
|
const flattenedComments = flattenComments(commentsData);
|
||||||
|
const totalComments = flattenedComments.length;
|
||||||
|
let currentIndex = 0;
|
||||||
|
|
||||||
|
// 初始化弹幕插件
|
||||||
|
let barrage = new Barrage.default({
|
||||||
|
el: 'body',
|
||||||
|
backColor: "#000000b5",
|
||||||
|
fontSize: "14px",
|
||||||
|
isLeft: true,
|
||||||
|
speed: 0,
|
||||||
|
height: "33px"
|
||||||
|
});
|
||||||
|
|
||||||
|
if (totalComments !== 0) {
|
||||||
|
while (currentIndex < totalComments) {
|
||||||
|
const currentComment = flattenedComments[currentIndex];
|
||||||
|
const barragerItem = {
|
||||||
|
headImg: "https://cravatar.cn/avatar/"+currentComment.email_encrypted + "?s=33" || 'static/default-avatar.png',
|
||||||
|
content: stripHTML(currentComment.content_marked) || 'No comment',
|
||||||
|
href: currentComment.link || '#',
|
||||||
|
speed: 10
|
||||||
|
};
|
||||||
|
|
||||||
|
// 发送弹幕
|
||||||
|
barrage.start(barragerItem.content, {
|
||||||
|
speed: barragerItem.speed,
|
||||||
|
headImg: barragerItem.headImg,
|
||||||
|
speed: 35
|
||||||
|
});
|
||||||
|
|
||||||
|
currentIndex++;
|
||||||
|
await delay(looperTime); // 等待指定的时间再发送下一条弹幕
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 延迟函数,返回一个 Promise,用于等待指定的毫秒数
|
||||||
|
function delay(ms) {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除 HTML 标签的函数
|
||||||
|
function stripHTML(html) {
|
||||||
|
return html.replace(/<\/?[^>]+(>|$)/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 展平评论数据结构的函数
|
||||||
|
function flattenComments(comments) {
|
||||||
|
let result = [];
|
||||||
|
comments.forEach(function (comment) {
|
||||||
|
result.push(comment);
|
||||||
|
if (comment.children && comment.children.length > 0) {
|
||||||
|
result = result.concat(flattenComments(comment.children));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用异步的弹幕加载函数
|
||||||
|
if (document.querySelector("#Comments") && !isMobile()) {
|
||||||
|
loadBarrager()
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentTheme() {
|
||||||
|
var theme = document.documentElement.getAttribute('data-theme');
|
||||||
|
if (!theme) {
|
||||||
|
theme = 'light';
|
||||||
|
}
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyTheme(theme) {
|
||||||
|
document.documentElement.setAttribute('data-theme', theme);
|
||||||
|
try {
|
||||||
|
localStorage.setItem('theme', theme);
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateThemeToggle(theme) {
|
||||||
|
var button = document.getElementById('theme-toggle');
|
||||||
|
if (theme === 'dark') {
|
||||||
|
if (button) {
|
||||||
|
button.textContent = '日间';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (button) {
|
||||||
|
button.textContent = '夜间';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleTheme() {
|
||||||
|
var current = getCurrentTheme();
|
||||||
|
var next = current === 'dark' ? 'light' : 'dark';
|
||||||
|
applyTheme(next);
|
||||||
|
updateThemeToggle(next);
|
||||||
|
if (window.Artalk && window.Artalk.get) {
|
||||||
|
try {
|
||||||
|
var ctx = Artalk.get('#Comments');
|
||||||
|
if (ctx && ctx.setDarkMode) {
|
||||||
|
ctx.setDarkMode(next === 'dark');
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
var theme = getCurrentTheme();
|
||||||
|
updateThemeToggle(theme);
|
||||||
|
var button = document.getElementById('theme-toggle');
|
||||||
|
if (button) {
|
||||||
|
button.addEventListener('click', toggleTheme);
|
||||||
|
}
|
||||||
|
var avatarWrapper = document.querySelector('.head_author_img');
|
||||||
|
var avatarTip = document.querySelector('.avatar-theme-tip');
|
||||||
|
if (avatarWrapper) {
|
||||||
|
avatarWrapper.style.cursor = 'pointer';
|
||||||
|
avatarWrapper.addEventListener('click', toggleTheme);
|
||||||
|
}
|
||||||
|
if (avatarTip) {
|
||||||
|
avatarTip.classList.add('is-visible');
|
||||||
|
var hideOnce = function () {
|
||||||
|
avatarTip.classList.add('is-hidden');
|
||||||
|
};
|
||||||
|
setTimeout(hideOnce, 9000);
|
||||||
|
if (avatarWrapper) {
|
||||||
|
avatarWrapper.addEventListener('click', hideOnce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 代码复制功能
|
||||||
|
function initCodeCopy() {
|
||||||
|
var codeBlocks = document.querySelectorAll('.highlight');
|
||||||
|
codeBlocks.forEach(function(block) {
|
||||||
|
if (block.querySelector('.copy-code-btn')) return;
|
||||||
|
|
||||||
|
var btn = document.createElement('button');
|
||||||
|
btn.className = 'copy-code-btn';
|
||||||
|
btn.innerHTML = '<i class="ri-file-copy-line"></i>';
|
||||||
|
block.appendChild(btn);
|
||||||
|
|
||||||
|
btn.addEventListener('click', function() {
|
||||||
|
var code = block.querySelector('code').innerText;
|
||||||
|
navigator.clipboard.writeText(code).then(function() {
|
||||||
|
btn.innerHTML = '<i class="ri-check-line"></i>';
|
||||||
|
setTimeout(function() {
|
||||||
|
btn.innerHTML = '<i class="ri-file-copy-line"></i>';
|
||||||
|
}, 2000);
|
||||||
|
}).catch(function(err) {
|
||||||
|
console.error('Failed to copy: ', err);
|
||||||
|
btn.innerText = 'Error';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面加载完成后初始化
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
initCodeCopy();
|
||||||
|
});
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -16,18 +16,21 @@
|
|||||||
<a href="#" id="back-to-top" title="返回顶部">
|
<a href="#" id="back-to-top" title="返回顶部">
|
||||||
<i class="ri-arrow-up-s-line"></i>
|
<i class="ri-arrow-up-s-line"></i>
|
||||||
</a>
|
</a>
|
||||||
<script src="/js/iconfont.js"></script>
|
{{ $iconfont := resources.Get "js/iconfont.js" }}
|
||||||
<script src="/js/lightgallery.umd.min.js"></script>
|
{{ $lightgallery := resources.Get "js/lightgallery.umd.min.js" }}
|
||||||
<script src="/js/uikit.min.js"></script>
|
{{ $uikit := resources.Get "js/uikit.min.js" }}
|
||||||
<script src="/js/EasyLazyload.min.js"></script>
|
{{ $easylazyload := resources.Get "js/EasyLazyload.min.js" }}
|
||||||
<script src="/js/view-image.min.js"></script>
|
{{ $viewimage := resources.Get "js/view-image.min.js" }}
|
||||||
<script src="/js/Artalk.js"></script>
|
{{ $artalk := resources.Get "js/Artalk.js" }}
|
||||||
<script src="/js/main.js"></script>
|
{{ $main := resources.Get "js/main.js" }}
|
||||||
<script src="/js/mypjax.js"></script>
|
{{ $mypjax := resources.Get "js/mypjax.js" }}
|
||||||
<script src="/js/nprogress.js"></script>
|
{{ $nprogress := resources.Get "js/nprogress.js" }}
|
||||||
<script src="/js/echarts.min.js"></script>
|
{{ $echarts := resources.Get "js/echarts.min.js" }}
|
||||||
<script src="/js/tiaozhuan.js"></script>
|
{{ $tiaozhuan := resources.Get "js/tiaozhuan.js" }}
|
||||||
<script async src="/js/bsz.js"></script>
|
{{ $bsz := resources.Get "js/bsz.js" }}
|
||||||
|
|
||||||
|
{{ $scripts := slice $iconfont $lightgallery $uikit $easylazyload $viewimage $artalk $main $mypjax $nprogress $echarts $tiaozhuan $bsz | resources.Concat "js/bundle.js" | resources.Minify | resources.Fingerprint }}
|
||||||
|
<script src="{{ $scripts.RelPermalink }}"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -2,6 +2,40 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
<title>{{ .Title }}</title>
|
<title>{{ .Title }}</title>
|
||||||
|
<!-- SEO & Meta Tags -->
|
||||||
|
<meta name="description" content="{{ if .IsHome }}{{ .Site.Params.description }}{{ else }}{{ .Description | default .Summary | plainify | truncate 160 }}{{ end }}" />
|
||||||
|
<link rel="canonical" href="{{ .Permalink }}" />
|
||||||
|
|
||||||
|
{{- $keywords := slice "大学" "教程" "blog" "优世界" "优设计" "博客" "大学生博客" "生活" "文案" -}}
|
||||||
|
{{- if .Params.tags -}}
|
||||||
|
{{- $keywords = .Params.tags -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- if .Params.keywords -}}
|
||||||
|
{{- $keywords = .Params.keywords -}}
|
||||||
|
{{- end -}}
|
||||||
|
<meta name="keywords" content="{{ delimit $keywords "," }}" />
|
||||||
|
|
||||||
|
<!-- Open Graph -->
|
||||||
|
<meta property="og:title" content="{{ .Title }}" />
|
||||||
|
<meta property="og:description" content="{{ if .IsHome }}{{ .Site.Params.description }}{{ else }}{{ .Description | default .Summary | plainify | truncate 160 }}{{ end }}" />
|
||||||
|
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}" />
|
||||||
|
<meta property="og:url" content="{{ .Permalink }}" />
|
||||||
|
<meta property="og:site_name" content="{{ .Site.Title }}" />
|
||||||
|
|
||||||
|
{{- $image := .Site.Params.authorImage -}}
|
||||||
|
{{- if .Params.cover -}}
|
||||||
|
{{- $image = .Params.cover -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $image -}}
|
||||||
|
<meta property="og:image" content="{{ $image | absURL }}" />
|
||||||
|
<meta name="twitter:image" content="{{ $image | absURL }}" />
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
<!-- Twitter Card -->
|
||||||
|
<meta name="twitter:card" content="summary" />
|
||||||
|
<meta name="twitter:title" content="{{ .Title }}" />
|
||||||
|
<meta name="twitter:description" content="{{ if .IsHome }}{{ .Site.Params.description }}{{ else }}{{ .Description | default .Summary | plainify | truncate 160 }}{{ end }}" />
|
||||||
|
|
||||||
<!-- RSS Feed -->
|
<!-- RSS Feed -->
|
||||||
<link rel="alternate" type="application/rss+xml" title="{{ site.Title }}" href="/rss.xml">
|
<link rel="alternate" type="application/rss+xml" title="{{ site.Title }}" href="/rss.xml">
|
||||||
<!-- Favicon -->
|
<!-- Favicon -->
|
||||||
@@ -22,12 +56,15 @@
|
|||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
<!-- Stylesheets -->
|
<!-- Stylesheets -->
|
||||||
<link rel="stylesheet" href="/css/normalize.css">
|
{{ $normalize := resources.Get "css/normalize.css" }}
|
||||||
<link rel="stylesheet" href="/css/remixicon.css">
|
{{ $remixicon := resources.Get "css/remixicon.css" }}
|
||||||
<link rel="stylesheet" href="/css/uikit.min.css">
|
{{ $uikit := resources.Get "css/uikit.min.css" }}
|
||||||
<link rel="stylesheet" href="/css/nprogress.min.css">
|
{{ $nprogress := resources.Get "css/nprogress.min.css" }}
|
||||||
<link rel="stylesheet" href="/css/Artalk.css">
|
{{ $artalk := resources.Get "css/Artalk.css" }}
|
||||||
<link rel='stylesheet' href='/css/main.css'>
|
{{ $main := resources.Get "css/main.css" }}
|
||||||
|
|
||||||
|
{{ $style := slice $normalize $remixicon $uikit $nprogress $artalk $main | resources.Concat "css/style.css" | resources.Minify | resources.Fingerprint }}
|
||||||
|
<link rel="stylesheet" href="{{ $style.RelPermalink }}">
|
||||||
<style>
|
<style>
|
||||||
@media only screen and (max-width: 768px) {
|
@media only screen and (max-width: 768px) {
|
||||||
.items {
|
.items {
|
||||||
@@ -140,6 +177,5 @@
|
|||||||
<link rel="stylesheet" href="/css/mywaline.css" />
|
<link rel="stylesheet" href="/css/mywaline.css" />
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<script>console.log("\n %c Amigo Theme %c https://usj.cc \n", "color: #fadfa3; background: #030307; padding:3px; font-size:12px;", "color: #ffffff;background: #16171a; padding: 3px; font-size: 12px;");</script>
|
<script>console.log("\n %c Amigo Theme %c https://usj.cc \n", "color: #fadfa3; background: #030307; padding:3px; font-size:12px;", "color: #ffffff;background: #16171a; padding: 3px; font-size: 12px;");</script>
|
||||||
<meta name="keywords" content="大学,教程,blog,优世界,优设计,博客,大学生博客,生活,文案," />
|
|
||||||
<meta name="template" content="Amigo" />
|
<meta name="template" content="Amigo" />
|
||||||
</head>
|
</head>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/echarts/5.3.0-rc.1/echarts.min.js"></script>
|
|
||||||
<div id="heatmap-wrapper" class="heatmap-scroll-wrapper">
|
<div id="heatmap-wrapper" class="heatmap-scroll-wrapper">
|
||||||
<div id="heatmap" style="max-width: 800px; height: 160px; margin: 0 auto 0px auto; padding: 10px; border-radius: 10px; transition: all 0.3s ease; display: block !important; visibility: visible !important; min-width: 300px;"></div>
|
<div id="heatmap" style="max-width: 800px; height: 160px; margin: 0 auto 0px auto; padding: 10px; border-radius: 10px; transition: all 0.3s ease; display: block !important; visibility: visible !important; min-width: 300px;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -1,279 +0,0 @@
|
|||||||
// 判断是否为移动端
|
|
||||||
function isMobile() {
|
|
||||||
if (window.navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {
|
|
||||||
return true; // 移动端
|
|
||||||
} else {
|
|
||||||
return false; // PC端
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 文章图片灯箱
|
|
||||||
window.ViewImage && ViewImage.init('.post-content img');
|
|
||||||
|
|
||||||
// Pure JavaScript Back to Top (High Performance)
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
var backToTopButton = document.getElementById('back-to-top');
|
|
||||||
if (backToTopButton) {
|
|
||||||
var isVisible = false;
|
|
||||||
var ticking = false;
|
|
||||||
|
|
||||||
function update() {
|
|
||||||
if (window.scrollY > 300) {
|
|
||||||
if (!isVisible) {
|
|
||||||
backToTopButton.classList.add('show');
|
|
||||||
isVisible = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (isVisible) {
|
|
||||||
backToTopButton.classList.remove('show');
|
|
||||||
isVisible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ticking = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('scroll', function() {
|
|
||||||
if (!ticking) {
|
|
||||||
window.requestAnimationFrame(update);
|
|
||||||
ticking = true;
|
|
||||||
}
|
|
||||||
}, { passive: true });
|
|
||||||
|
|
||||||
backToTopButton.addEventListener('click', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
window.scrollTo({
|
|
||||||
top: 0,
|
|
||||||
behavior: 'smooth'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// loader定时器
|
|
||||||
$(document).ready(function () {
|
|
||||||
setTimeout(function () {
|
|
||||||
$("#loader").addClass("hide");
|
|
||||||
}, 30000);
|
|
||||||
});
|
|
||||||
// 点击进入按钮
|
|
||||||
$("#closeloader").click(function () {
|
|
||||||
$("#loader").addClass("hide");
|
|
||||||
});
|
|
||||||
// nav栏样式调整
|
|
||||||
$('#libabys').first().attr("style", "margin-left: -5px");
|
|
||||||
|
|
||||||
$('#libabys').eq(1).attr("style", "margin-left: -5px");
|
|
||||||
// 友链列表版样式调整
|
|
||||||
$('.itp-index:odd').attr("style", "float: right;width:48%;");
|
|
||||||
|
|
||||||
//文章图片懒加载
|
|
||||||
lazyLoadInit({
|
|
||||||
// coverColor: "white",
|
|
||||||
// coverDiv: "<div style='display: flex; justify-content: center; align-items: center; height: 200px; color: #000000;'><span>优世界·一个记录生活点滴的小站</span></div>",
|
|
||||||
offsetBottom: 800,
|
|
||||||
offsetTopm: 800,
|
|
||||||
showTime: 1100
|
|
||||||
});
|
|
||||||
|
|
||||||
async function loadBarrager() {
|
|
||||||
try {
|
|
||||||
const commentsData = await initArtalkAndGetComments();
|
|
||||||
if (commentsData) {
|
|
||||||
await createBarragerFromArtalk(commentsData);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('加载弹幕时发生错误:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 异步初始化 Artalk 并获取评论数据
|
|
||||||
function initArtalkAndGetComments() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
Artalk.use((ctx) => {
|
|
||||||
ctx.on('list-loaded', () => {
|
|
||||||
console.log('评论列表加载完毕');
|
|
||||||
const commentsData = ctx.getComments();
|
|
||||||
if (commentsData) {
|
|
||||||
resolve(commentsData);
|
|
||||||
// console.log(commentsData);
|
|
||||||
} else {
|
|
||||||
reject('获取评论数据失败');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Artalk.init({
|
|
||||||
el: '#Comments', // 绑定元素的 Selector
|
|
||||||
server: 'https://artalk.usj.cc', // 后端地址
|
|
||||||
site: '优世界', // 你的站点名
|
|
||||||
flatMode: true,
|
|
||||||
emoticons: '/emotion/OwO.json'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 异步创建弹幕
|
|
||||||
async function createBarragerFromArtalk(commentsData) {
|
|
||||||
const looperTime = 1000; // 每条弹幕的发送间隔,单位毫秒
|
|
||||||
const flattenedComments = flattenComments(commentsData);
|
|
||||||
const totalComments = flattenedComments.length;
|
|
||||||
let currentIndex = 0;
|
|
||||||
|
|
||||||
// 初始化弹幕插件
|
|
||||||
let barrage = new Barrage.default({
|
|
||||||
el: 'body',
|
|
||||||
backColor: "#000000b5",
|
|
||||||
fontSize: "14px",
|
|
||||||
isLeft: true,
|
|
||||||
speed: 0,
|
|
||||||
height: "33px"
|
|
||||||
});
|
|
||||||
|
|
||||||
if (totalComments !== 0) {
|
|
||||||
while (currentIndex < totalComments) {
|
|
||||||
const currentComment = flattenedComments[currentIndex];
|
|
||||||
const barragerItem = {
|
|
||||||
headImg: "https://cravatar.cn/avatar/"+currentComment.email_encrypted + "?s=33" || 'static/default-avatar.png',
|
|
||||||
content: stripHTML(currentComment.content_marked) || 'No comment',
|
|
||||||
href: currentComment.link || '#',
|
|
||||||
speed: 10
|
|
||||||
};
|
|
||||||
|
|
||||||
// 发送弹幕
|
|
||||||
barrage.start(barragerItem.content, {
|
|
||||||
speed: barragerItem.speed,
|
|
||||||
headImg: barragerItem.headImg,
|
|
||||||
speed: 35
|
|
||||||
});
|
|
||||||
|
|
||||||
currentIndex++;
|
|
||||||
await delay(looperTime); // 等待指定的时间再发送下一条弹幕
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 延迟函数,返回一个 Promise,用于等待指定的毫秒数
|
|
||||||
function delay(ms) {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 去除 HTML 标签的函数
|
|
||||||
function stripHTML(html) {
|
|
||||||
return html.replace(/<\/?[^>]+(>|$)/g, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 展平评论数据结构的函数
|
|
||||||
function flattenComments(comments) {
|
|
||||||
let result = [];
|
|
||||||
comments.forEach(function (comment) {
|
|
||||||
result.push(comment);
|
|
||||||
if (comment.children && comment.children.length > 0) {
|
|
||||||
result = result.concat(flattenComments(comment.children));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 调用异步的弹幕加载函数
|
|
||||||
if (document.querySelector("#Comments") && !isMobile()) {
|
|
||||||
loadBarrager()
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentTheme() {
|
|
||||||
var theme = document.documentElement.getAttribute('data-theme');
|
|
||||||
if (!theme) {
|
|
||||||
theme = 'light';
|
|
||||||
}
|
|
||||||
return theme;
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyTheme(theme) {
|
|
||||||
document.documentElement.setAttribute('data-theme', theme);
|
|
||||||
try {
|
|
||||||
localStorage.setItem('theme', theme);
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateThemeToggle(theme) {
|
|
||||||
var button = document.getElementById('theme-toggle');
|
|
||||||
if (theme === 'dark') {
|
|
||||||
if (button) {
|
|
||||||
button.textContent = '日间';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (button) {
|
|
||||||
button.textContent = '夜间';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleTheme() {
|
|
||||||
var current = getCurrentTheme();
|
|
||||||
var next = current === 'dark' ? 'light' : 'dark';
|
|
||||||
applyTheme(next);
|
|
||||||
updateThemeToggle(next);
|
|
||||||
if (window.Artalk && window.Artalk.get) {
|
|
||||||
try {
|
|
||||||
var ctx = Artalk.get('#Comments');
|
|
||||||
if (ctx && ctx.setDarkMode) {
|
|
||||||
ctx.setDarkMode(next === 'dark');
|
|
||||||
}
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
|
||||||
var theme = getCurrentTheme();
|
|
||||||
updateThemeToggle(theme);
|
|
||||||
var button = document.getElementById('theme-toggle');
|
|
||||||
if (button) {
|
|
||||||
button.addEventListener('click', toggleTheme);
|
|
||||||
}
|
|
||||||
var avatarWrapper = document.querySelector('.head_author_img');
|
|
||||||
var avatarTip = document.querySelector('.avatar-theme-tip');
|
|
||||||
if (avatarWrapper) {
|
|
||||||
avatarWrapper.style.cursor = 'pointer';
|
|
||||||
avatarWrapper.addEventListener('click', toggleTheme);
|
|
||||||
}
|
|
||||||
if (avatarTip) {
|
|
||||||
avatarTip.classList.add('is-visible');
|
|
||||||
var hideOnce = function () {
|
|
||||||
avatarTip.classList.add('is-hidden');
|
|
||||||
};
|
|
||||||
setTimeout(hideOnce, 9000);
|
|
||||||
if (avatarWrapper) {
|
|
||||||
avatarWrapper.addEventListener('click', hideOnce);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 代码复制功能
|
|
||||||
function initCodeCopy() {
|
|
||||||
var codeBlocks = document.querySelectorAll('.highlight');
|
|
||||||
codeBlocks.forEach(function(block) {
|
|
||||||
if (block.querySelector('.copy-code-btn')) return;
|
|
||||||
|
|
||||||
var btn = document.createElement('button');
|
|
||||||
btn.className = 'copy-code-btn';
|
|
||||||
btn.innerHTML = '<i class="ri-file-copy-line"></i>';
|
|
||||||
block.appendChild(btn);
|
|
||||||
|
|
||||||
btn.addEventListener('click', function() {
|
|
||||||
var code = block.querySelector('code').innerText;
|
|
||||||
navigator.clipboard.writeText(code).then(function() {
|
|
||||||
btn.innerHTML = '<i class="ri-check-line"></i>';
|
|
||||||
setTimeout(function() {
|
|
||||||
btn.innerHTML = '<i class="ri-file-copy-line"></i>';
|
|
||||||
}, 2000);
|
|
||||||
}).catch(function(err) {
|
|
||||||
console.error('Failed to copy: ', err);
|
|
||||||
btn.innerText = 'Error';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 页面加载完成后初始化
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
initCodeCopy();
|
|
||||||
});
|
|
||||||
Reference in new issue
Block a user