优化一下博客的性能
This commit is contained in:
1 parent
39b69bf850
commit
1c3401ee79
24 files changed
+2045
-148
No files matched your search
+12
-1
@@ -12,7 +12,18 @@
|
|||||||
"Read(//e/GitHub/Another-Blog/content/posts/2026/202605091914/**)",
|
"Read(//e/GitHub/Another-Blog/content/posts/2026/202605091914/**)",
|
||||||
"Read(//e/GitHub/Another-Blog/content/posts/2026/202605091921/**)",
|
"Read(//e/GitHub/Another-Blog/content/posts/2026/202605091921/**)",
|
||||||
"Read(//e/GitHub/Another-Blog/content/posts/2026/202604300006/**)",
|
"Read(//e/GitHub/Another-Blog/content/posts/2026/202604300006/**)",
|
||||||
"Bash(cmd //c \"taskkill /F /PID 40384\")"
|
"Bash(cmd //c \"taskkill /F /PID 40384\")",
|
||||||
|
"PowerShell(try { $r = Invoke-WebRequest -UseBasicParsing http://127.0.0.1:1316/circles.html; 'OK' } catch { $_.Exception.Message })",
|
||||||
|
"Bash(\"/c/Program Files/Google/Chrome/Application/chrome.exe\" --headless=new --disable-gpu --virtual-time-budget=12000 --dump-dom \"http://127.0.0.1:1316/links.html\")",
|
||||||
|
"Bash(\"/c/Program Files/Google/Chrome/Application/chrome.exe\" --headless=new --disable-gpu --virtual-time-budget=12000 --dump-dom \"http://127.0.0.1:1316/circles.html\")",
|
||||||
|
"Bash(curl -s http://127.0.0.1:1316/links.html -o E:\\\\GitHub\\\\blog\\\\.tmp-links.html)",
|
||||||
|
"Bash(curl -s http://127.0.0.1:1316/circles.html -o E:\\\\GitHub\\\\blog\\\\.tmp-circles.html)",
|
||||||
|
"Bash(curl -s -o \".tmp-links.html\" http://127.0.0.1:1316/links.html)",
|
||||||
|
"Bash(curl -s -o \".tmp-circles.html\" http://127.0.0.1:1316/circles.html)",
|
||||||
|
"Bash(curl -s http://127.0.0.1:1316/ -o \".tmp-index.html\")",
|
||||||
|
"Bash(curl -s \"http://127.0.0.1:1316/js/bundle.min.ca22314448750e3cd87573167443c4f61447dd8c77fdb2a8ecf962e6e770a7b7.js\" -o \".tmp-bundle.js\")",
|
||||||
|
"Bash([ ! -x \"$CHROME\" ])",
|
||||||
|
"Bash(powershell -c \"\\(Get-Command chrome.exe\\).Source\")"
|
||||||
],
|
],
|
||||||
"additionalDirectories": [
|
"additionalDirectories": [
|
||||||
"E:\\GitHub\\Another-Blog"
|
"E:\\GitHub\\Another-Blog"
|
||||||
|
|||||||
+1
Submodule .claude/worktrees/agent-a29465a348705c475 added at 39b69bf850.
+1
Submodule .claude/worktrees/agent-a41f7b6fbd8eb1368 added at 39b69bf850.
+1
Submodule .claude/worktrees/agent-a88ac4fa046a2faca added at 39b69bf850.
+1
Submodule .claude/worktrees/agent-a97b858be06004781 added at 39b69bf850.
@@ -0,0 +1,969 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-cn">
|
||||||
|
|
||||||
|
<head><script src="/livereload.js?mindelay=10&v=2&port=1316&path=livereload" data-no-instant defer></script>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
|
<title>友圈</title>
|
||||||
|
|
||||||
|
<meta name="description" content="" />
|
||||||
|
<link rel="canonical" href="http://localhost:1316/circles.html" /><meta name="keywords" content="大学,教程,blog,优世界,优设计,博客,大学生博客,生活,文案" />
|
||||||
|
|
||||||
|
|
||||||
|
<meta property="og:title" content="友圈" />
|
||||||
|
<meta property="og:description" content="" />
|
||||||
|
<meta property="og:type" content="article" />
|
||||||
|
<meta property="og:url" content="http://localhost:1316/circles.html" />
|
||||||
|
<meta property="og:site_name" content="优世界" />
|
||||||
|
<meta name="twitter:card" content="summary" />
|
||||||
|
<meta name="twitter:title" content="友圈" />
|
||||||
|
<meta name="twitter:description" content="" />
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="alternate" type="application/rss+xml" title="优世界" href="/rss.xml">
|
||||||
|
|
||||||
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||||||
|
|
||||||
|
<script async src="https://019e3dec-3312-7873-862a-3f56ac99ea83.spst2.com/ustat.js"></script>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
try {
|
||||||
|
var theme = localStorage.getItem('theme');
|
||||||
|
if (!theme) {
|
||||||
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
|
theme = 'dark';
|
||||||
|
} else {
|
||||||
|
theme = 'light';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.documentElement.setAttribute('data-theme', theme);
|
||||||
|
|
||||||
|
|
||||||
|
if (window.matchMedia) {
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!localStorage.getItem('theme')) {
|
||||||
|
var newTheme = event.matches ? "dark" : "light";
|
||||||
|
document.documentElement.setAttribute('data-theme', newTheme);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<link rel="preload" href="/font/zql-v2.woff2" as="font" type="font/woff2" crossorigin>
|
||||||
|
<link rel="preload" href="/font/remixicon.woff2" as="font" type="font/woff2" crossorigin>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.siteConfig = {
|
||||||
|
artalk: {
|
||||||
|
server: "https:\/\/artalk.usj.cc",
|
||||||
|
site: "优世界",
|
||||||
|
emoticons: "http:\/\/localhost:1316\/emotion\/OwO.json",
|
||||||
|
gravatar: "https:\/\/cravatar.cn\/avatar\/"
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
avatar: "\/image\/avatar\/tx7.jpg",
|
||||||
|
description: "不以物喜,不以己悲"
|
||||||
|
},
|
||||||
|
barrage: {
|
||||||
|
enableHitokoto: true ,
|
||||||
|
hitokotoUrl: "https:\/\/v1.hitokoto.cn?c=a\u0026c=b\u0026c=c\u0026c=d\u0026c=i"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/css/style.min.7201c0e9ef7fa574d6fbab1efcb309790f11bbf063b86f0d8d36527afe7d209b.css">
|
||||||
|
<link rel="stylesheet" href="/css/libs/Artalk.min.c18a4adffe1319c3471e50565ff505ca8ca75eaf46d5661085de4918f94d6b4c.css"><style>
|
||||||
|
body, [data-theme="dark"] body {
|
||||||
|
background-image: url('/image/background/deno.webp') !important;
|
||||||
|
background-size: contain !important;
|
||||||
|
background-repeat: round !important;
|
||||||
|
background-position: center !important;
|
||||||
|
background-attachment: fixed !important;
|
||||||
|
}
|
||||||
|
</style><style>
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
.items {
|
||||||
|
grid-template-columns: repeat(1, 1fr) !important;
|
||||||
|
grid-gap: 10px;
|
||||||
|
}
|
||||||
|
.link-des,.link-name{
|
||||||
|
right: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.items {
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-gap: 10px;
|
||||||
|
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-box {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 8px;
|
||||||
|
|
||||||
|
height: 300px;
|
||||||
|
|
||||||
|
box-shadow: rgba(14, 63, 126, 0.04) 0px 0px 0px 1px, rgba(42, 51, 69, 0.04) 0px 1px 1px -0.5px, rgba(42, 51, 70, 0.04) 0px 3px 3px -1.5px, rgba(42, 51, 70, 0.04) 0px 6px 6px -3px, rgba(14, 63, 126, 0.04) 0px 12px 12px -6px, rgba(14, 63, 126, 0.04) 0px 24px 24px -12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.website-img {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.website-img img {
|
||||||
|
width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.website-go-button {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 95%;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 5px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-info {
|
||||||
|
padding: 8px;
|
||||||
|
width: 100%;
|
||||||
|
height: 90px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-avatar {
|
||||||
|
width: 40%;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-avatar img {
|
||||||
|
position: relative;
|
||||||
|
left: 5px;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-text-main {
|
||||||
|
width: 55%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-name {
|
||||||
|
position: relative;
|
||||||
|
right: 10px;
|
||||||
|
bottom: 5px;
|
||||||
|
width: 100%;
|
||||||
|
height: 50%;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-des {
|
||||||
|
position: relative;
|
||||||
|
right: 10px;
|
||||||
|
top: 1px;
|
||||||
|
width: 100%;
|
||||||
|
height: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script src="/js/instantpage.min.js" type="module" defer></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="template" content="Amigo" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.barrageConfig = {
|
||||||
|
enableHitokoto: true ,
|
||||||
|
hitokotoUrl: "https:\/\/v1.hitokoto.cn?c=a\u0026c=b\u0026c=c\u0026c=d\u0026c=i",
|
||||||
|
hitokotoAvatar: "\/image\/avatar\/tx7.jpg"
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<div class="barrager"></div>
|
||||||
|
|
||||||
|
<div class="main">
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<div class="header-top">
|
||||||
|
<div class="header-avatar load-memos-editor" id="theme-toggle-avatar">
|
||||||
|
<img src="/image/avatar/tx7.jpg" class="blog-img" width="80" height="80" alt="优世界" decoding="async" fetchpriority="high" />
|
||||||
|
<div class="avatar-theme-tip">
|
||||||
|
点击头像切换昼夜
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="header-info">
|
||||||
|
<div class="header-social ">
|
||||||
|
|
||||||
|
|
||||||
|
<a href="https://github.com/zqlit" title="GitHub" target="_blank"><i class="ri-github-fill"></i></a>
|
||||||
|
|
||||||
|
<a href="#" title="我的主页" target="_blank"><i class="ri-at-line"></i></a>
|
||||||
|
|
||||||
|
<a href="/rss.xml" title="Rss订阅" target="_blank"><i class="ri-rss-fill"></i></a>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="header-bio ">不以物喜,不以己悲</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<nav class="header-menu">
|
||||||
|
<ul class="flat">
|
||||||
|
|
||||||
|
<li class="active "><a href="/">首页</a></li>
|
||||||
|
|
||||||
|
<li class="active "><a href="/about.html">关于</a></li>
|
||||||
|
|
||||||
|
<li class="active "><a href="/circles.html">友圈</a></li>
|
||||||
|
|
||||||
|
<li class="active "><a href="/comment.html">留言</a></li>
|
||||||
|
|
||||||
|
<li class="active "><a href="/archives.html">归档</a></li>
|
||||||
|
|
||||||
|
<li class="active "><a href="/links.html">友链</a></li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="pjax-wrapper" style="position: relative; min-height: 50vh;">
|
||||||
|
|
||||||
|
<div id="pjax-container">
|
||||||
|
<div class="post-content" itemprop="articleBody">
|
||||||
|
|
||||||
|
<div id="friend-circle-container" class="friend-circle-list">
|
||||||
|
<div class="loading-container">
|
||||||
|
<div class="loading-spinner"></div>
|
||||||
|
<p>正在探索朋友们的新动态...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.friend-circle-list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 12px;
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.friend-circle-list {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.fc-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
position: relative;
|
||||||
|
height: 160px;
|
||||||
|
justify-content: space-between;
|
||||||
|
background: rgba(255, 255, 255, 0.4);
|
||||||
|
backdrop-filter: blur(12px) saturate(120%);
|
||||||
|
-webkit-backdrop-filter: blur(12px) saturate(120%);
|
||||||
|
border: 1px solid #111827;
|
||||||
|
box-shadow: none;
|
||||||
|
transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.25, 1), box-shadow 0.3s ease, background-color 0.3s ease, border-color 0.3s ease;
|
||||||
|
will-change: transform;
|
||||||
|
text-decoration: none;
|
||||||
|
transform: translateZ(0);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.fc-item {
|
||||||
|
backdrop-filter: none !important;
|
||||||
|
-webkit-backdrop-filter: none !important;
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
}
|
||||||
|
[data-theme="dark"] .fc-item {
|
||||||
|
background: rgba(30, 30, 30, 0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.friend-circle-list a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--fc-text: #333;
|
||||||
|
--fc-meta-bg: rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] {
|
||||||
|
--fc-text: #fff;
|
||||||
|
--fc-meta-bg: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-item:hover {
|
||||||
|
transform: translateY(-6px) scale(1.015);
|
||||||
|
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.1), 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||||
|
background: rgba(255, 255, 255, 0.7);
|
||||||
|
border-color: #1a1a1a;
|
||||||
|
z-index: 10;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-item:active {
|
||||||
|
transform: translateY(-3px) scale(1.005);
|
||||||
|
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--fc-text);
|
||||||
|
text-decoration: none;
|
||||||
|
line-height: 1.4;
|
||||||
|
z-index: 2;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-right: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-item:hover .fc-title {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-bg-image {
|
||||||
|
position: absolute;
|
||||||
|
right: -20px;
|
||||||
|
bottom: -20px;
|
||||||
|
width: 140px;
|
||||||
|
height: 140px;
|
||||||
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
|
opacity: 0.15;
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
z-index: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
filter: grayscale(20%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-item:hover .fc-bg-image {
|
||||||
|
opacity: 0.3;
|
||||||
|
transform: scale(1.1) rotate(deg);
|
||||||
|
filter: grayscale(0%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-bottom {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-end;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-author-pill {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: var(--fc-meta-bg);
|
||||||
|
padding: 4px 10px 4px 4px;
|
||||||
|
border-radius: 20px;
|
||||||
|
transition: background 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-item:hover .fc-author-pill {
|
||||||
|
background: rgba(52, 152, 219, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-avatar {
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
|
margin-right: 8px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-author-name {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--fc-text);
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-date {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--fc-text);
|
||||||
|
opacity: 0.6;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-date i {
|
||||||
|
margin-right: 4px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-icon-calendar::before {
|
||||||
|
content: "\f133";
|
||||||
|
font-family: "Font Awesome 5 Free", "FontAwesome";
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-container {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 60px;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-spinner {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border: 3px solid rgba(127, 127, 127, 0.2);
|
||||||
|
border-radius: 50%;
|
||||||
|
border-top-color: #3498db;
|
||||||
|
animation: spin 1s ease-in-out infinite;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .fc-item {
|
||||||
|
background: rgba(35, 35, 35, 0.65);
|
||||||
|
box-shadow: none;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .fc-author-pill {
|
||||||
|
background: #1a1a1a;
|
||||||
|
border: 1px solid #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .fc-bg-image {
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .fc-item:hover {
|
||||||
|
background: rgba(60, 60, 60, 0.85);
|
||||||
|
border-color: rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .fc-item:hover .fc-title {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-load-more-btn {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
padding: 5px 30px;
|
||||||
|
margin: 30px auto 10px;
|
||||||
|
background: #000;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 30px;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-load-more-btn:hover {
|
||||||
|
background: #333;
|
||||||
|
color: #fff;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .fc-load-more-btn {
|
||||||
|
background: #000;
|
||||||
|
border-color: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .fc-load-more-btn:hover {
|
||||||
|
background: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .artalk .atk-main-editor {
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-tooltip {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 9999;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 16px;
|
||||||
|
width: 300px;
|
||||||
|
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.95) translateY(10px);
|
||||||
|
transition: opacity 0.2s ease, transform 0.2s ease;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: #333;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-tooltip.is-visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1) translateY(0);
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-tooltip-title {
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #000;
|
||||||
|
border-bottom: 1px solid rgba(0,0,0,0.05);
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-tooltip-content {
|
||||||
|
color: #555;
|
||||||
|
text-align: justify;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 6;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .fc-tooltip {
|
||||||
|
background: rgba(35, 35, 35, 0.95);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .fc-tooltip-title {
|
||||||
|
color: #fff;
|
||||||
|
border-bottom-color: rgba(255,255,255,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .fc-tooltip-content {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="fc-tooltip" class="fc-tooltip">
|
||||||
|
<div class="fc-tooltip-title"></div>
|
||||||
|
<div class="fc-tooltip-content"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.FriendCircle = {
|
||||||
|
allPosts: [],
|
||||||
|
currentIndex: 0,
|
||||||
|
BATCH_SIZE: 10,
|
||||||
|
CACHE_KEY: 'friend-circle-v1',
|
||||||
|
CACHE_OPTIONS: {
|
||||||
|
version: 2,
|
||||||
|
softTtl: 5 * 60 * 1000,
|
||||||
|
hardTtl: 60 * 60 * 1000,
|
||||||
|
validate: function(data) {
|
||||||
|
return !!data && Array.isArray(data.posts);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
timeAgo: function (dateStr) {
|
||||||
|
const date = new Date(dateStr);
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||||
|
const day = String(date.getDate()).padStart(2, "0");
|
||||||
|
return year + "-" + month + "-" + day;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderPosts: function (posts) {
|
||||||
|
const container = document.getElementById("friend-circle-container");
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
const existingBtn = document.getElementById("fc-load-more-btn");
|
||||||
|
if (existingBtn) existingBtn.remove();
|
||||||
|
|
||||||
|
let html = "";
|
||||||
|
posts.forEach((post, index) => {
|
||||||
|
const dateStr = this.timeAgo(post.date);
|
||||||
|
const bgImageSrc = post.avatar;
|
||||||
|
const description = post.description ? post.description.replace(/"/g, '"') : '';
|
||||||
|
const delay = index * 100;
|
||||||
|
|
||||||
|
html += '<a href="' + post.link + '" target="_blank" class="fc-item" data-desc="' + description + '" data-title="' + post.title + '" uk-scrollspy="cls: uk-animation-slide-bottom-small; delay: ' + delay + '">'
|
||||||
|
+ '<div class="fc-title" title="' + post.title + '">' + post.title + '</div>'
|
||||||
|
+ '<img src="' + bgImageSrc + '" class="fc-bg-image" onerror="this.style.opacity=0">'
|
||||||
|
+ '<div class="fc-bottom">'
|
||||||
|
+ '<div class="fc-author-pill">'
|
||||||
|
+ '<img src="' + post.avatar + '" class="fc-avatar" onerror="this.src=\'https://cravatar.cn/avatar/default?s=50\'">'
|
||||||
|
+ '<span class="fc-author-name">' + post.author + '</span>'
|
||||||
|
+ '</div>'
|
||||||
|
+ '<div class="fc-date"><i class="ri-calendar-line"></i> ' + dateStr + '</div>'
|
||||||
|
+ '</div>'
|
||||||
|
+ '</a>';
|
||||||
|
});
|
||||||
|
|
||||||
|
container.insertAdjacentHTML("beforeend", html);
|
||||||
|
|
||||||
|
if (this.currentIndex < this.allPosts.length) {
|
||||||
|
const btn = document.createElement("button");
|
||||||
|
btn.id = "fc-load-more-btn";
|
||||||
|
btn.className = "fc-load-more-btn";
|
||||||
|
btn.innerText = "加载更多";
|
||||||
|
btn.onclick = function() { window.FriendCircle.loadMore(); };
|
||||||
|
container.appendChild(btn);
|
||||||
|
} else {
|
||||||
|
if (window.fcUpdateTime) {
|
||||||
|
const footer = document.createElement("div");
|
||||||
|
footer.style.cssText = "grid-column: 1 / -1; text-align: center; margin-top: 20px; font-size: 12px; color: #999; opacity: 0.6;";
|
||||||
|
footer.innerText = "最近更新: " + window.fcUpdateTime;
|
||||||
|
container.appendChild(footer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
loadMore: function () {
|
||||||
|
const nextBatch = this.allPosts.slice(
|
||||||
|
this.currentIndex,
|
||||||
|
this.currentIndex + this.BATCH_SIZE
|
||||||
|
);
|
||||||
|
this.currentIndex += this.BATCH_SIZE;
|
||||||
|
requestAnimationFrame(function() {
|
||||||
|
window.FriendCircle.renderPosts(nextBatch);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
renderEmpty: function () {
|
||||||
|
const container = document.getElementById("friend-circle-container");
|
||||||
|
if (!container) return;
|
||||||
|
container.innerHTML = '<div class="empty" style="grid-column: 1/-1; text-align:center; padding:20px;">暂无动态</div>';
|
||||||
|
},
|
||||||
|
|
||||||
|
renderError: function () {
|
||||||
|
const container = document.getElementById("friend-circle-container");
|
||||||
|
if (!container) return;
|
||||||
|
container.innerHTML = '<div class="error" style="grid-column: 1/-1; text-align:center; padding:20px; color:#d9534f;">加载失败,请稍后刷新重试</div>';
|
||||||
|
},
|
||||||
|
|
||||||
|
applyData: function (data) {
|
||||||
|
const container = document.getElementById("friend-circle-container");
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
if (!data.posts || data.posts.length === 0) {
|
||||||
|
this.renderEmpty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.FriendCircle.allPosts = data.posts;
|
||||||
|
window.fcUpdateTime = new Date(data.updated).toLocaleString();
|
||||||
|
window.FriendCircle.currentIndex = 0;
|
||||||
|
container.innerHTML = "";
|
||||||
|
window.FriendCircle.loadMore();
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchData: function () {
|
||||||
|
if (window.BrowserCache && typeof window.BrowserCache.log === 'function') {
|
||||||
|
window.BrowserCache.log('[FriendCircleCache][fetch]', {
|
||||||
|
key: window.BrowserCache ? window.BrowserCache.buildKey(window.FriendCircle.CACHE_KEY) : window.FriendCircle.CACHE_KEY,
|
||||||
|
softTtl: window.BrowserCache ? window.BrowserCache.formatDuration(window.FriendCircle.CACHE_OPTIONS.softTtl) : window.FriendCircle.CACHE_OPTIONS.softTtl,
|
||||||
|
hardTtl: window.BrowserCache ? window.BrowserCache.formatDuration(window.FriendCircle.CACHE_OPTIONS.hardTtl) : window.FriendCircle.CACHE_OPTIONS.hardTtl
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return fetch("https://rssapi.usj.cc/api/articles?limit=50")
|
||||||
|
.then(function(res) {
|
||||||
|
if (!res.ok) throw new Error("Network response was not ok");
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(function(apiData) {
|
||||||
|
const posts = (apiData.articles || []).map(function(a) {
|
||||||
|
return {
|
||||||
|
title: a.title || '',
|
||||||
|
link: a.link || '',
|
||||||
|
date: a.pubDate || '',
|
||||||
|
author: a.feedName || a.author || '',
|
||||||
|
avatar: a.favicon || '',
|
||||||
|
blogUrl: a.siteUrl || '',
|
||||||
|
image: null,
|
||||||
|
description: ''
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
posts: posts,
|
||||||
|
updated: apiData.timestamp || new Date().toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (window.BrowserCache) {
|
||||||
|
window.BrowserCache.write(window.FriendCircle.CACHE_KEY, window.FriendCircle.CACHE_OPTIONS, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
initTooltip: function() {
|
||||||
|
if (this.tooltipInitialized) return;
|
||||||
|
this.tooltipInitialized = true;
|
||||||
|
|
||||||
|
const tooltip = document.getElementById('fc-tooltip');
|
||||||
|
const titleEl = tooltip.querySelector('.fc-tooltip-title');
|
||||||
|
const contentEl = tooltip.querySelector('.fc-tooltip-content');
|
||||||
|
const container = document.getElementById('friend-circle-container');
|
||||||
|
|
||||||
|
if (!tooltip || !container) return;
|
||||||
|
|
||||||
|
if (tooltip.parentNode !== document.body) {
|
||||||
|
document.body.appendChild(tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cleanup = function() {
|
||||||
|
if (tooltip && tooltip.parentNode === document.body) {
|
||||||
|
tooltip.remove();
|
||||||
|
}
|
||||||
|
document.removeEventListener('pjax:send', cleanup);
|
||||||
|
};
|
||||||
|
document.addEventListener('pjax:send', cleanup);
|
||||||
|
|
||||||
|
const updateTooltip = function(e) {
|
||||||
|
if (window.innerWidth <= 768) return;
|
||||||
|
const item = e.target.closest('.fc-item');
|
||||||
|
if (item) {
|
||||||
|
const desc = item.getAttribute('data-desc');
|
||||||
|
const title = item.getAttribute('data-title');
|
||||||
|
if (desc) {
|
||||||
|
titleEl.innerText = title;
|
||||||
|
contentEl.innerText = desc;
|
||||||
|
tooltip.classList.add('is-visible');
|
||||||
|
const tooltipWidth = tooltip.offsetWidth;
|
||||||
|
const tooltipHeight = tooltip.offsetHeight;
|
||||||
|
const winWidth = window.innerWidth;
|
||||||
|
const winHeight = window.innerHeight;
|
||||||
|
const gap = 15;
|
||||||
|
let left = e.clientX + gap;
|
||||||
|
let top = e.clientY + gap;
|
||||||
|
if (left + tooltipWidth > winWidth - gap) {
|
||||||
|
left = e.clientX - tooltipWidth - gap;
|
||||||
|
if (left < gap) left = gap;
|
||||||
|
}
|
||||||
|
if (top + tooltipHeight > winHeight - gap) {
|
||||||
|
top = e.clientY - tooltipHeight - gap;
|
||||||
|
if (top < gap) top = gap;
|
||||||
|
}
|
||||||
|
tooltip.style.left = left + 'px';
|
||||||
|
tooltip.style.top = top + 'px';
|
||||||
|
} else {
|
||||||
|
tooltip.classList.remove('is-visible');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tooltip.classList.remove('is-visible');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
container.addEventListener('mousemove', updateTooltip);
|
||||||
|
container.addEventListener('mouseleave', function() {
|
||||||
|
tooltip.classList.remove('is-visible');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
init: function () {
|
||||||
|
const container = document.getElementById("friend-circle-container");
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
this.initTooltip();
|
||||||
|
|
||||||
|
if (this.isFetching) return;
|
||||||
|
this.isFetching = true;
|
||||||
|
|
||||||
|
const cached = window.BrowserCache && window.BrowserCache.read(this.CACHE_KEY, this.CACHE_OPTIONS);
|
||||||
|
if (cached) {
|
||||||
|
if (window.BrowserCache && typeof window.BrowserCache.log === 'function') {
|
||||||
|
window.BrowserCache.log('[FriendCircleCache][render]', {
|
||||||
|
key: cached.key,
|
||||||
|
age: cached.ageText,
|
||||||
|
isFresh: cached.isFresh,
|
||||||
|
softTtl: cached.softTtlText,
|
||||||
|
hardTtl: cached.hardTtlText
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.applyData(cached.data);
|
||||||
|
if (cached.isFresh) {
|
||||||
|
this.isFetching = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fetchData()
|
||||||
|
.then(function(data) {
|
||||||
|
window.FriendCircle.applyData(data);
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
if (window.BrowserCache && window.BrowserCache.isDebug && window.BrowserCache.isDebug()) {
|
||||||
|
console.error("Friend Circle Error:", err);
|
||||||
|
}
|
||||||
|
if (!cached) {
|
||||||
|
window.FriendCircle.renderError();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(function() {
|
||||||
|
window.FriendCircle.isFetching = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function initFriendCirclePage() {
|
||||||
|
if (window.FriendCircle && typeof window.FriendCircle.init === 'function') {
|
||||||
|
window.FriendCircle.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('pjax:complete', initFriendCirclePage);
|
||||||
|
|
||||||
|
if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", initFriendCirclePage);
|
||||||
|
} else {
|
||||||
|
initFriendCirclePage();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<nav class="nav" style="clear: both;">
|
||||||
|
© 2019 - 2026
|
||||||
|
<br>
|
||||||
|
<a href="https://beian.miit.gov.cn/" target="_blank"><span style="color:#999999;">鄂ICP备2022015735号-1</span></a>
|
||||||
|
<br>
|
||||||
|
本站由<a href="https://www.upyun.com/?utm_source=lianmeng&utm_medium=referral" target="blank" title="又拍云"
|
||||||
|
style="display:inline-block;text-decoration:none;height:20px;line-height:20px;">
|
||||||
|
<span style="color: var(--contentColor);font-weight: 700;">又拍云CDN</span>
|
||||||
|
</a>提供CDN加速服务
|
||||||
|
<br>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="floating-tools">
|
||||||
|
<a href="javascript:;" id="search-btn" title="搜索文章">
|
||||||
|
<i class="ri-search-line"></i>
|
||||||
|
</a>
|
||||||
|
<a href="javascript:;" id="theme-toggle" title="切换主题">
|
||||||
|
<i class="ri-sun-line"></i>
|
||||||
|
</a>
|
||||||
|
<a href="#Comments" id="to-comments" title="跳转评论">
|
||||||
|
<i class="ri-chat-2-line"></i>
|
||||||
|
</a>
|
||||||
|
<a href="#" id="back-to-top" title="返回顶部">
|
||||||
|
<i class="ri-arrow-up-line"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="search-modal" class="search-modal">
|
||||||
|
<div class="search-modal-content">
|
||||||
|
<div class="search-header">
|
||||||
|
<h3>搜索文章</h3>
|
||||||
|
<span class="close-search">×</span>
|
||||||
|
</div>
|
||||||
|
<div class="search-body">
|
||||||
|
<div class="search-input-wrapper">
|
||||||
|
<input type="text" id="search-input" placeholder="输入关键词搜索..." autocomplete="off">
|
||||||
|
<button id="search-submit"><i class="ri-search-line"></i></button>
|
||||||
|
</div>
|
||||||
|
<div id="search-results" class="search-results">
|
||||||
|
|
||||||
|
<p class="search-tip">输入关键词并回车进行搜索</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script defer src="/js/bundle.min.ca22314448750e3cd87573167443c4f61447dd8c77fdb2a8ecf962e6e770a7b7.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
window.enableInfiniteScroll = false ;
|
||||||
|
</script>
|
||||||
|
<script async src="/js/bsz.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,536 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-cn">
|
||||||
|
|
||||||
|
<head><script src="/livereload.js?mindelay=10&v=2&port=1316&path=livereload" data-no-instant defer></script>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
|
<title>友链</title>
|
||||||
|
|
||||||
|
<meta name="description" content="" />
|
||||||
|
<link rel="canonical" href="http://localhost:1316/links.html" /><meta name="keywords" content="大学,教程,blog,优世界,优设计,博客,大学生博客,生活,文案" />
|
||||||
|
|
||||||
|
|
||||||
|
<meta property="og:title" content="友链" />
|
||||||
|
<meta property="og:description" content="" />
|
||||||
|
<meta property="og:type" content="article" />
|
||||||
|
<meta property="og:url" content="http://localhost:1316/links.html" />
|
||||||
|
<meta property="og:site_name" content="优世界" />
|
||||||
|
<meta name="twitter:card" content="summary" />
|
||||||
|
<meta name="twitter:title" content="友链" />
|
||||||
|
<meta name="twitter:description" content="" />
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="alternate" type="application/rss+xml" title="优世界" href="/rss.xml">
|
||||||
|
|
||||||
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||||||
|
|
||||||
|
<script async src="https://019e3dec-3312-7873-862a-3f56ac99ea83.spst2.com/ustat.js"></script>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
try {
|
||||||
|
var theme = localStorage.getItem('theme');
|
||||||
|
if (!theme) {
|
||||||
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
|
theme = 'dark';
|
||||||
|
} else {
|
||||||
|
theme = 'light';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.documentElement.setAttribute('data-theme', theme);
|
||||||
|
|
||||||
|
|
||||||
|
if (window.matchMedia) {
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!localStorage.getItem('theme')) {
|
||||||
|
var newTheme = event.matches ? "dark" : "light";
|
||||||
|
document.documentElement.setAttribute('data-theme', newTheme);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<link rel="preload" href="/font/zql-v2.woff2" as="font" type="font/woff2" crossorigin>
|
||||||
|
<link rel="preload" href="/font/remixicon.woff2" as="font" type="font/woff2" crossorigin>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.siteConfig = {
|
||||||
|
artalk: {
|
||||||
|
server: "https:\/\/artalk.usj.cc",
|
||||||
|
site: "优世界",
|
||||||
|
emoticons: "http:\/\/localhost:1316\/emotion\/OwO.json",
|
||||||
|
gravatar: "https:\/\/cravatar.cn\/avatar\/"
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
avatar: "\/image\/avatar\/tx7.jpg",
|
||||||
|
description: "不以物喜,不以己悲"
|
||||||
|
},
|
||||||
|
barrage: {
|
||||||
|
enableHitokoto: true ,
|
||||||
|
hitokotoUrl: "https:\/\/v1.hitokoto.cn?c=a\u0026c=b\u0026c=c\u0026c=d\u0026c=i"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/css/style.min.7201c0e9ef7fa574d6fbab1efcb309790f11bbf063b86f0d8d36527afe7d209b.css">
|
||||||
|
<link rel="stylesheet" href="/css/libs/Artalk.min.c18a4adffe1319c3471e50565ff505ca8ca75eaf46d5661085de4918f94d6b4c.css"><style>
|
||||||
|
body, [data-theme="dark"] body {
|
||||||
|
background-image: url('/image/background/deno.webp') !important;
|
||||||
|
background-size: contain !important;
|
||||||
|
background-repeat: round !important;
|
||||||
|
background-position: center !important;
|
||||||
|
background-attachment: fixed !important;
|
||||||
|
}
|
||||||
|
</style><style>
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
.items {
|
||||||
|
grid-template-columns: repeat(1, 1fr) !important;
|
||||||
|
grid-gap: 10px;
|
||||||
|
}
|
||||||
|
.link-des,.link-name{
|
||||||
|
right: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.items {
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-gap: 10px;
|
||||||
|
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-box {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 8px;
|
||||||
|
|
||||||
|
height: 300px;
|
||||||
|
|
||||||
|
box-shadow: rgba(14, 63, 126, 0.04) 0px 0px 0px 1px, rgba(42, 51, 69, 0.04) 0px 1px 1px -0.5px, rgba(42, 51, 70, 0.04) 0px 3px 3px -1.5px, rgba(42, 51, 70, 0.04) 0px 6px 6px -3px, rgba(14, 63, 126, 0.04) 0px 12px 12px -6px, rgba(14, 63, 126, 0.04) 0px 24px 24px -12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.website-img {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.website-img img {
|
||||||
|
width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.website-go-button {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 95%;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 5px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-info {
|
||||||
|
padding: 8px;
|
||||||
|
width: 100%;
|
||||||
|
height: 90px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-avatar {
|
||||||
|
width: 40%;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-avatar img {
|
||||||
|
position: relative;
|
||||||
|
left: 5px;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-text-main {
|
||||||
|
width: 55%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-name {
|
||||||
|
position: relative;
|
||||||
|
right: 10px;
|
||||||
|
bottom: 5px;
|
||||||
|
width: 100%;
|
||||||
|
height: 50%;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-des {
|
||||||
|
position: relative;
|
||||||
|
right: 10px;
|
||||||
|
top: 1px;
|
||||||
|
width: 100%;
|
||||||
|
height: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script src="/js/instantpage.min.js" type="module" defer></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="template" content="Amigo" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.barrageConfig = {
|
||||||
|
enableHitokoto: true ,
|
||||||
|
hitokotoUrl: "https:\/\/v1.hitokoto.cn?c=a\u0026c=b\u0026c=c\u0026c=d\u0026c=i",
|
||||||
|
hitokotoAvatar: "\/image\/avatar\/tx7.jpg"
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<div class="barrager"></div>
|
||||||
|
|
||||||
|
<div class="main">
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<div class="header-top">
|
||||||
|
<div class="header-avatar load-memos-editor" id="theme-toggle-avatar">
|
||||||
|
<img src="/image/avatar/tx7.jpg" class="blog-img" width="80" height="80" alt="优世界" decoding="async" fetchpriority="high" />
|
||||||
|
<div class="avatar-theme-tip">
|
||||||
|
点击头像切换昼夜
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="header-info">
|
||||||
|
<div class="header-social ">
|
||||||
|
|
||||||
|
|
||||||
|
<a href="https://github.com/zqlit" title="GitHub" target="_blank"><i class="ri-github-fill"></i></a>
|
||||||
|
|
||||||
|
<a href="#" title="我的主页" target="_blank"><i class="ri-at-line"></i></a>
|
||||||
|
|
||||||
|
<a href="/rss.xml" title="Rss订阅" target="_blank"><i class="ri-rss-fill"></i></a>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="header-bio ">不以物喜,不以己悲</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<nav class="header-menu">
|
||||||
|
<ul class="flat">
|
||||||
|
|
||||||
|
<li class="active "><a href="/">首页</a></li>
|
||||||
|
|
||||||
|
<li class="active "><a href="/about.html">关于</a></li>
|
||||||
|
|
||||||
|
<li class="active "><a href="/circles.html">友圈</a></li>
|
||||||
|
|
||||||
|
<li class="active "><a href="/comment.html">留言</a></li>
|
||||||
|
|
||||||
|
<li class="active "><a href="/archives.html">归档</a></li>
|
||||||
|
|
||||||
|
<li class="active "><a href="/links.html">友链</a></li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="pjax-wrapper" style="position: relative; min-height: 50vh;">
|
||||||
|
|
||||||
|
<div id="pjax-container">
|
||||||
|
<style>
|
||||||
|
.links ul>li {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 1.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.links a {
|
||||||
|
color: var(--link-color-light);
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.links li {
|
||||||
|
margin-top: .5em;
|
||||||
|
margin-bottom: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.links ul>li:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
background-color: #d1d5db;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: .375em;
|
||||||
|
height: .375em;
|
||||||
|
top: .6875em;
|
||||||
|
left: .25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-name {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-name::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
height: 12px;
|
||||||
|
bottom: 3px;
|
||||||
|
left: -4px;
|
||||||
|
z-index: -1;
|
||||||
|
background-color: #5d5d5d;
|
||||||
|
opacity: .3;
|
||||||
|
transform: skew(-35deg);
|
||||||
|
transition: opacity .2s ease;
|
||||||
|
border-radius: 3px 8px 10px 6px;
|
||||||
|
transition: 0.1s ease background-color;
|
||||||
|
width: 112%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-name:hover::before {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .links a {
|
||||||
|
color: var(--link-color-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .url-name::before {
|
||||||
|
background-color: #e5e7eb;
|
||||||
|
opacity: 0.18;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .url-name:hover::before {
|
||||||
|
opacity: 0.35;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="post-content" itemprop="articleBody">
|
||||||
|
<div class="links">
|
||||||
|
<ul id="links-list" uk-scrollspy="target: > li; cls: uk-animation-slide-bottom-small; delay: 50">
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var list = document.getElementById('links-list');
|
||||||
|
if (!list) return;
|
||||||
|
|
||||||
|
var CACHE_KEY = 'friend-links-v1';
|
||||||
|
var CACHE_OPTIONS = {
|
||||||
|
version: 2,
|
||||||
|
softTtl: 6 * 60 * 60 * 1000,
|
||||||
|
hardTtl: 24 * 60 * 60 * 1000,
|
||||||
|
validate: function(data) {
|
||||||
|
return !!data && Array.isArray(data.links);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function escapeHtml(value) {
|
||||||
|
return String(value || '')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''');
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderState(message, className) {
|
||||||
|
list.innerHTML = '<li class="' + className + '">' + escapeHtml(message) + '</li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderLinks(links) {
|
||||||
|
if (!Array.isArray(links) || links.length === 0) {
|
||||||
|
renderState('暂无友链数据', 'links-empty');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
links.forEach(function(l) {
|
||||||
|
html += '<li><a href="' + escapeHtml(l.url) + '" class="url-name" target="_blank" rel="noopener noreferrer">' + escapeHtml(l.name) + '</a><span style="margin-left: 13px;">' + escapeHtml(l.description || '') + '</span></li>';
|
||||||
|
});
|
||||||
|
list.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function logCache(event, payload) {
|
||||||
|
if (window.BrowserCache && typeof window.BrowserCache.log === 'function') {
|
||||||
|
window.BrowserCache.log('[LinksCache][' + event + ']', payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchLinks() {
|
||||||
|
logCache('fetch', {
|
||||||
|
key: window.BrowserCache ? window.BrowserCache.buildKey(CACHE_KEY) : CACHE_KEY,
|
||||||
|
softTtl: window.BrowserCache ? window.BrowserCache.formatDuration(CACHE_OPTIONS.softTtl) : CACHE_OPTIONS.softTtl,
|
||||||
|
hardTtl: window.BrowserCache ? window.BrowserCache.formatDuration(CACHE_OPTIONS.hardTtl) : CACHE_OPTIONS.hardTtl
|
||||||
|
});
|
||||||
|
return fetch('https://rssapi.usj.cc/api/links')
|
||||||
|
.then(function(res) {
|
||||||
|
if (!res.ok) throw new Error('Failed to fetch links');
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(function(data) {
|
||||||
|
var links = Array.isArray(data.links) ? data.links : [];
|
||||||
|
var payload = { links: links };
|
||||||
|
window.BrowserCache.write(CACHE_KEY, CACHE_OPTIONS, payload);
|
||||||
|
return payload;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var cached = window.BrowserCache && window.BrowserCache.read(CACHE_KEY, CACHE_OPTIONS);
|
||||||
|
if (cached) {
|
||||||
|
logCache('render', {
|
||||||
|
key: cached.key,
|
||||||
|
age: cached.ageText,
|
||||||
|
isFresh: cached.isFresh,
|
||||||
|
softTtl: cached.softTtlText,
|
||||||
|
hardTtl: cached.hardTtlText
|
||||||
|
});
|
||||||
|
renderLinks(cached.data.links);
|
||||||
|
if (cached.isFresh) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
renderState('友链加载中...', 'links-loading');
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchLinks()
|
||||||
|
.then(function(payload) {
|
||||||
|
renderLinks(payload.links);
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
if (window.BrowserCache && window.BrowserCache.isDebug && window.BrowserCache.isDebug()) {
|
||||||
|
console.error('Links Error:', err);
|
||||||
|
}
|
||||||
|
if (!cached) {
|
||||||
|
renderState('友链加载失败,请稍后刷新重试', 'links-error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<nav class="nav" style="clear: both;">
|
||||||
|
© 2019 - 2026
|
||||||
|
<br>
|
||||||
|
<a href="https://beian.miit.gov.cn/" target="_blank"><span style="color:#999999;">鄂ICP备2022015735号-1</span></a>
|
||||||
|
<br>
|
||||||
|
本站由<a href="https://www.upyun.com/?utm_source=lianmeng&utm_medium=referral" target="blank" title="又拍云"
|
||||||
|
style="display:inline-block;text-decoration:none;height:20px;line-height:20px;">
|
||||||
|
<span style="color: var(--contentColor);font-weight: 700;">又拍云CDN</span>
|
||||||
|
</a>提供CDN加速服务
|
||||||
|
<br>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="floating-tools">
|
||||||
|
<a href="javascript:;" id="search-btn" title="搜索文章">
|
||||||
|
<i class="ri-search-line"></i>
|
||||||
|
</a>
|
||||||
|
<a href="javascript:;" id="theme-toggle" title="切换主题">
|
||||||
|
<i class="ri-sun-line"></i>
|
||||||
|
</a>
|
||||||
|
<a href="#Comments" id="to-comments" title="跳转评论">
|
||||||
|
<i class="ri-chat-2-line"></i>
|
||||||
|
</a>
|
||||||
|
<a href="#" id="back-to-top" title="返回顶部">
|
||||||
|
<i class="ri-arrow-up-line"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="search-modal" class="search-modal">
|
||||||
|
<div class="search-modal-content">
|
||||||
|
<div class="search-header">
|
||||||
|
<h3>搜索文章</h3>
|
||||||
|
<span class="close-search">×</span>
|
||||||
|
</div>
|
||||||
|
<div class="search-body">
|
||||||
|
<div class="search-input-wrapper">
|
||||||
|
<input type="text" id="search-input" placeholder="输入关键词搜索..." autocomplete="off">
|
||||||
|
<button id="search-submit"><i class="ri-search-line"></i></button>
|
||||||
|
</div>
|
||||||
|
<div id="search-results" class="search-results">
|
||||||
|
|
||||||
|
<p class="search-tip">输入关键词并回车进行搜索</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script defer src="/js/bundle.min.ca22314448750e3cd87573167443c4f61447dd8c77fdb2a8ecf962e6e770a7b7.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
window.enableInfiniteScroll = false ;
|
||||||
|
</script>
|
||||||
|
<script async src="/js/bsz.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
||||||
+2
-2
@@ -14,10 +14,10 @@ draft: false
|
|||||||
<h3 class="uk-card-title uk-margin-remove-bottom" style="font-size: 1.2rem; font-weight: 600;"><i class="ri-user-smile-line uk-margin-small-right"></i>关于博主</h3>
|
<h3 class="uk-card-title uk-margin-remove-bottom" style="font-size: 1.2rem; font-weight: 600;"><i class="ri-user-smile-line uk-margin-small-right"></i>关于博主</h3>
|
||||||
<p class="uk-text-meta uk-margin-remove-top uk-margin-small-bottom">Hello, World!</p>
|
<p class="uk-text-meta uk-margin-remove-top uk-margin-small-bottom">Hello, World!</p>
|
||||||
<div class="uk-margin-small-top">
|
<div class="uk-margin-small-top">
|
||||||
<p class="uk-margin-small-bottom"><i class="ri-map-pin-user-line uk-margin-small-right"></i>湖北 · 襄阳 -> 武汉</p>
|
<p class="uk-margin-small-bottom"><i class="ri-map-pin-user-line uk-margin-small-right"></i>湖北 · 襄阳 -> 深圳</p>
|
||||||
<p class="uk-margin-small-bottom"><i class="ri-user-heart-line uk-margin-small-right"></i>00后,性格随和,风趣幽默</p>
|
<p class="uk-margin-small-bottom"><i class="ri-user-heart-line uk-margin-small-right"></i>00后,性格随和,风趣幽默</p>
|
||||||
<p class="uk-margin-small-bottom"><i class="ri-flag-line uk-margin-small-right"></i>未来计划定居江苏南京</p>
|
<p class="uk-margin-small-bottom"><i class="ri-flag-line uk-margin-small-right"></i>未来计划定居江苏南京</p>
|
||||||
<p class="uk-margin-remove-bottom"><i class="ri-briefcase-line uk-margin-small-right"></i>工作:运维工程师</p>
|
<p class="uk-margin-remove-bottom"><i class="ri-briefcase-line uk-margin-small-right"></i>工作:待业</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -513,8 +513,8 @@ ul {
|
|||||||
z-index: 10;
|
z-index: 10;
|
||||||
position: relative;
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(6px);
|
||||||
-webkit-backdrop-filter: blur(10px);
|
-webkit-backdrop-filter: blur(6px);
|
||||||
/* Smoother transition */
|
/* Smoother transition */
|
||||||
transition: background-color 0.5s cubic-bezier(0.4, 0, 0.2, 1),
|
transition: background-color 0.5s cubic-bezier(0.4, 0, 0.2, 1),
|
||||||
color 0.5s cubic-bezier(0.4, 0, 0.2, 1);
|
color 0.5s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
@@ -528,15 +528,26 @@ ul {
|
|||||||
contain-intrinsic-size: 1000px;
|
contain-intrinsic-size: 1000px;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
/* Mobile Optimization: Remove expensive effects */
|
@media (min-width: 768px) {
|
||||||
@media (max-width: 767px) {
|
.main {
|
||||||
.main,
|
background: rgba(255, 255, 255, 0.88);
|
||||||
[data-theme="dark"] .main,
|
-webkit-backdrop-filter: blur(6px);
|
||||||
.artalk-related,
|
backdrop-filter: blur(6px);
|
||||||
.floating-tools {
|
}
|
||||||
backdrop-filter: none !important;
|
|
||||||
-webkit-backdrop-filter: none !important;
|
[data-theme="dark"] #pjax-loading-skeleton {
|
||||||
box-shadow: none !important;
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.floating-tools a {
|
||||||
|
-webkit-backdrop-filter: blur(4px) saturate(140%);
|
||||||
|
backdrop-filter: blur(4px) saturate(140%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.atk-loading {
|
||||||
|
-webkit-backdrop-filter: none;
|
||||||
|
backdrop-filter: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1825,7 +1836,8 @@ darkb-text:active {
|
|||||||
[data-theme="dark"] #pjax-loading-skeleton {
|
[data-theme="dark"] #pjax-loading-skeleton {
|
||||||
background: rgba(15, 23, 42, 0.94) !important;
|
background: rgba(15, 23, 42, 0.94) !important;
|
||||||
box-shadow: var(--card-shadow-dark) !important;
|
box-shadow: var(--card-shadow-dark) !important;
|
||||||
backdrop-filter: blur(18px);
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .skeleton-line {
|
[data-theme="dark"] .skeleton-line {
|
||||||
@@ -2969,6 +2981,17 @@ input[type=submit] {
|
|||||||
|
|
||||||
.lazyload {
|
.lazyload {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-content img,
|
||||||
|
.entry-content img {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
content-visibility: auto;
|
||||||
|
contain-intrinsic-size: 700px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 设置进度条的背景色 */
|
/* 设置进度条的背景色 */
|
||||||
@@ -3504,8 +3527,8 @@ input[type=submit] {
|
|||||||
/* Optimized transition: specific properties instead of all */
|
/* Optimized transition: specific properties instead of all */
|
||||||
transition: background-color 0.3s ease, color 0.3s ease, transform 0.3s ease, border-color 0.3s ease;
|
transition: background-color 0.3s ease, color 0.3s ease, transform 0.3s ease, border-color 0.3s ease;
|
||||||
/* Restored backdrop-filter */
|
/* Restored backdrop-filter */
|
||||||
backdrop-filter: blur(10px) saturate(180%);
|
backdrop-filter: blur(4px) saturate(140%);
|
||||||
-webkit-backdrop-filter: blur(10px) saturate(180%);
|
-webkit-backdrop-filter: blur(4px) saturate(140%);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.4);
|
border: 1px solid rgba(255, 255, 255, 0.4);
|
||||||
/* GPU Acceleration for individual items */
|
/* GPU Acceleration for individual items */
|
||||||
transform: translate3d(0, 0, 0);
|
transform: translate3d(0, 0, 0);
|
||||||
@@ -4060,8 +4083,8 @@ img[atk-emoticon] {
|
|||||||
background: rgba(255, 255, 255, 0.8) !important;
|
background: rgba(255, 255, 255, 0.8) !important;
|
||||||
box-shadow: none !important; /* 去除阴影,更简洁 */
|
box-shadow: none !important; /* 去除阴影,更简洁 */
|
||||||
border-radius: 8px !important;
|
border-radius: 8px !important;
|
||||||
backdrop-filter: blur(4px); /* 轻微模糊 */
|
backdrop-filter: none;
|
||||||
-webkit-backdrop-filter: blur(4px);
|
-webkit-backdrop-filter: none;
|
||||||
/* display: flex !important; <-- 移除这个强制显示 */
|
/* display: flex !important; <-- 移除这个强制显示 */
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -4747,17 +4770,17 @@ html[data-theme="light"] .atk-loading-spinner svg circle {
|
|||||||
|
|
||||||
/* Lazy Load Animation */
|
/* Lazy Load Animation */
|
||||||
.lazyload {
|
.lazyload {
|
||||||
opacity: 0;
|
opacity: 1;
|
||||||
transform: translateY(30px); /* 稍微增加位移距离,增强上浮感 */
|
transform: none;
|
||||||
filter: blur(5px); /* 减少模糊,避免过于影响性能 */
|
filter: none;
|
||||||
transition: opacity 0.8s ease-out, transform 0.8s cubic-bezier(0.215, 0.61, 0.355, 1), filter 0.8s ease-out; /* 使用 ease-out 和自定义贝塞尔曲线,模拟自然惯性 */
|
transition: none;
|
||||||
will-change: opacity, transform; /* 移除 filter 的 will-change 以节省内存 */
|
will-change: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lazyload.lazy-loaded {
|
.lazyload.lazy-loaded {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0);
|
transform: none;
|
||||||
filter: blur(0);
|
filter: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .ai-comment-card .atk-content p {
|
[data-theme="dark"] .ai-comment-card .atk-content p {
|
||||||
|
|||||||
@@ -0,0 +1,202 @@
|
|||||||
|
window.BrowserCache = (function () {
|
||||||
|
var PREFIX = 'ying-cache:';
|
||||||
|
var DEBUG_KEY = PREFIX + 'debug';
|
||||||
|
var DEBUG = detectDebug();
|
||||||
|
|
||||||
|
function detectDebug() {
|
||||||
|
try {
|
||||||
|
if (typeof window === 'undefined' || !window.location) return false;
|
||||||
|
var loc = window.location;
|
||||||
|
var host = loc.hostname || '';
|
||||||
|
var protocol = loc.protocol || '';
|
||||||
|
var search = loc.search || '';
|
||||||
|
|
||||||
|
// Explicit URL override wins over everything.
|
||||||
|
if (/(^|[?&])debug-cache=1(&|$)/.test(search)) return true;
|
||||||
|
if (/(^|[?&])debug-cache=0(&|$)/.test(search)) return false;
|
||||||
|
|
||||||
|
// Persisted toggle (set via setDebug) wins over auto-detection.
|
||||||
|
try {
|
||||||
|
var stored = localStorage.getItem(DEBUG_KEY);
|
||||||
|
if (stored === '1') return true;
|
||||||
|
if (stored === '0') return false;
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
// Auto-enable on local dev origins.
|
||||||
|
if (protocol === 'file:') return true;
|
||||||
|
if (host === 'localhost' || host === '127.0.0.1' || host === '0.0.0.0') return true;
|
||||||
|
} catch (e) {}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDebug(enabled) {
|
||||||
|
DEBUG = !!enabled;
|
||||||
|
try {
|
||||||
|
localStorage.setItem(DEBUG_KEY, DEBUG ? '1' : '0');
|
||||||
|
} catch (e) {}
|
||||||
|
return DEBUG;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDebug() {
|
||||||
|
return DEBUG;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isStorageAvailable() {
|
||||||
|
try {
|
||||||
|
var key = PREFIX + '__test__';
|
||||||
|
localStorage.setItem(key, '1');
|
||||||
|
localStorage.removeItem(key);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildKey(key) {
|
||||||
|
return PREFIX + key;
|
||||||
|
}
|
||||||
|
|
||||||
|
function log(tagOrEvent, payload) {
|
||||||
|
if (!DEBUG || typeof console === 'undefined' || !console.info) return;
|
||||||
|
var label = tagOrEvent && tagOrEvent.charAt(0) === '[' ? tagOrEvent : '[BrowserCache][' + tagOrEvent + ']';
|
||||||
|
console.info(label, payload || {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDuration(ms) {
|
||||||
|
if (!ms || ms <= 0) return '0s';
|
||||||
|
var totalSeconds = Math.floor(ms / 1000);
|
||||||
|
var hours = Math.floor(totalSeconds / 3600);
|
||||||
|
var minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||||
|
var seconds = totalSeconds % 60;
|
||||||
|
if (hours > 0) return hours + 'h ' + minutes + 'm';
|
||||||
|
if (minutes > 0) return minutes + 'm ' + seconds + 's';
|
||||||
|
return seconds + 's';
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove(key) {
|
||||||
|
if (!isStorageAvailable()) return;
|
||||||
|
try {
|
||||||
|
localStorage.removeItem(buildKey(key));
|
||||||
|
log('remove', { key: buildKey(key) });
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function read(key, options) {
|
||||||
|
options = options || {};
|
||||||
|
if (!isStorageAvailable()) {
|
||||||
|
log('storage-unavailable', { key: buildKey(key) });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fullKey = buildKey(key);
|
||||||
|
|
||||||
|
try {
|
||||||
|
var raw = localStorage.getItem(fullKey);
|
||||||
|
if (!raw) {
|
||||||
|
log('miss', { key: fullKey });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var payload = JSON.parse(raw);
|
||||||
|
if (!payload || typeof payload !== 'object') {
|
||||||
|
remove(key);
|
||||||
|
log('invalid-payload', { key: fullKey });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload.version !== options.version) {
|
||||||
|
remove(key);
|
||||||
|
log('version-mismatch', { key: fullKey, expected: options.version, actual: payload.version });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof payload.cachedAt !== 'number' || !('data' in payload)) {
|
||||||
|
remove(key);
|
||||||
|
log('invalid-shape', { key: fullKey });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof options.validate === 'function' && !options.validate(payload.data)) {
|
||||||
|
remove(key);
|
||||||
|
log('validate-failed', { key: fullKey });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var now = Date.now();
|
||||||
|
var age = now - payload.cachedAt;
|
||||||
|
var softTtl = options.softTtl || 0;
|
||||||
|
var hardTtl = options.hardTtl || softTtl;
|
||||||
|
|
||||||
|
if (hardTtl > 0 && age > hardTtl) {
|
||||||
|
remove(key);
|
||||||
|
log('expired', { key: fullKey, age: formatDuration(age), hardTtl: formatDuration(hardTtl) });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
key: fullKey,
|
||||||
|
data: payload.data,
|
||||||
|
cachedAt: payload.cachedAt,
|
||||||
|
age: age,
|
||||||
|
ageText: formatDuration(age),
|
||||||
|
softTtl: softTtl,
|
||||||
|
softTtlText: formatDuration(softTtl),
|
||||||
|
hardTtl: hardTtl,
|
||||||
|
hardTtlText: formatDuration(hardTtl),
|
||||||
|
isFresh: softTtl <= 0 || age <= softTtl,
|
||||||
|
isStale: softTtl > 0 && age > softTtl
|
||||||
|
};
|
||||||
|
|
||||||
|
log(result.isFresh ? 'hit-fresh' : 'hit-stale', {
|
||||||
|
key: fullKey,
|
||||||
|
age: result.ageText,
|
||||||
|
softTtl: result.softTtlText,
|
||||||
|
hardTtl: result.hardTtlText
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (e) {
|
||||||
|
remove(key);
|
||||||
|
log('parse-failed', { key: fullKey, message: e && e.message ? e.message : e });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function write(key, options, data) {
|
||||||
|
options = options || {};
|
||||||
|
if (!isStorageAvailable()) {
|
||||||
|
log('storage-unavailable', { key: buildKey(key) });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fullKey = buildKey(key);
|
||||||
|
|
||||||
|
try {
|
||||||
|
localStorage.setItem(fullKey, JSON.stringify({
|
||||||
|
version: options.version,
|
||||||
|
cachedAt: Date.now(),
|
||||||
|
data: data
|
||||||
|
}));
|
||||||
|
log('write', {
|
||||||
|
key: fullKey,
|
||||||
|
softTtl: formatDuration(options.softTtl || 0),
|
||||||
|
hardTtl: formatDuration(options.hardTtl || options.softTtl || 0)
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
if (DEBUG && typeof console !== 'undefined' && console.warn) {
|
||||||
|
console.warn('BrowserCache write failed:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
read: read,
|
||||||
|
write: write,
|
||||||
|
remove: remove,
|
||||||
|
buildKey: buildKey,
|
||||||
|
formatDuration: formatDuration,
|
||||||
|
log: log,
|
||||||
|
setDebug: setDebug,
|
||||||
|
isDebug: isDebug
|
||||||
|
};
|
||||||
|
})();
|
||||||
@@ -198,16 +198,21 @@ window.initFloatingTools = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (container) {
|
if (container) {
|
||||||
window.lightboxObserver = new MutationObserver(function(mutations) {
|
var syncLightboxState = function() {
|
||||||
var lightbox = document.querySelector('.view-image');
|
var lightbox = document.querySelector('.view-image');
|
||||||
if (lightbox) {
|
if (lightbox) {
|
||||||
container.classList.add('hidden');
|
container.classList.add('hidden');
|
||||||
} else {
|
} else {
|
||||||
container.classList.remove('hidden');
|
container.classList.remove('hidden');
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.lightboxObserver = new MutationObserver(function() {
|
||||||
|
syncLightboxState();
|
||||||
});
|
});
|
||||||
|
|
||||||
window.lightboxObserver.observe(document.body, { childList: true });
|
window.lightboxObserver.observe(document.body, { childList: true, subtree: true });
|
||||||
|
syncLightboxState();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -1,77 +1,59 @@
|
|||||||
(function() {
|
(function() {
|
||||||
// Default configuration
|
|
||||||
var defaults = {
|
var defaults = {
|
||||||
offsetBottom: 100, // Distance from bottom to start loading
|
offsetBottom: 100,
|
||||||
showTime: 1100, // Transition duration (ms)
|
showTime: 1100,
|
||||||
queueInterval: 200 // Time between showing successive images in queue
|
queueInterval: 200
|
||||||
};
|
};
|
||||||
|
|
||||||
var observer;
|
var observer;
|
||||||
var imageQueue = []; // Queue for images waiting to be shown
|
|
||||||
var isProcessingQueue = false;
|
|
||||||
|
|
||||||
function init(setting) {
|
function init(setting) {
|
||||||
// Merge settings
|
|
||||||
defaults = Object.assign({}, defaults, setting || {});
|
defaults = Object.assign({}, defaults, setting || {});
|
||||||
|
|
||||||
// Reset queue
|
|
||||||
imageQueue = [];
|
|
||||||
isProcessingQueue = false;
|
|
||||||
|
|
||||||
// Disconnect previous observer if exists (for PJAX)
|
|
||||||
if (observer) {
|
if (observer) {
|
||||||
observer.disconnect();
|
observer.disconnect();
|
||||||
observer = null;
|
observer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for IntersectionObserver support
|
|
||||||
if (!window.IntersectionObserver) {
|
if (!window.IntersectionObserver) {
|
||||||
loadAllImages();
|
loadAllImages();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize IntersectionObserver
|
|
||||||
observer = new IntersectionObserver(function(entries, self) {
|
observer = new IntersectionObserver(function(entries, self) {
|
||||||
entries.forEach(function(entry) {
|
entries.forEach(function(entry) {
|
||||||
if (entry.isIntersecting) {
|
if (!entry.isIntersecting) return;
|
||||||
var img = entry.target;
|
|
||||||
|
var img = entry.target;
|
||||||
// Load immediately without queue
|
loadImage(img);
|
||||||
loadImage(img);
|
self.unobserve(img);
|
||||||
|
|
||||||
// Stop observing this image once it's triggered
|
|
||||||
self.unobserve(img);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}, {
|
}, {
|
||||||
rootMargin: "0px 0px " + defaults.offsetBottom + "px 0px",
|
rootMargin: "0px 0px " + defaults.offsetBottom + "px 0px",
|
||||||
threshold: 0.01
|
threshold: 0.01
|
||||||
});
|
});
|
||||||
|
|
||||||
observeImages();
|
observeImages();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removed addToQueue and processQueue functions as we want instant loading
|
function getPendingImages() {
|
||||||
|
return document.querySelectorAll('img.lazyload[data-lazy-src], .post-content img[data-lazy-src]:not(.lazy-loaded)');
|
||||||
|
}
|
||||||
|
|
||||||
function observeImages() {
|
function observeImages() {
|
||||||
var images = document.querySelectorAll('img.lazyload, .post-content img:not(.lazy-loaded)');
|
var images = getPendingImages();
|
||||||
|
|
||||||
images.forEach(function(img) {
|
images.forEach(function(img) {
|
||||||
if (img.classList.contains('lazy-loaded')) return;
|
observer.observe(img);
|
||||||
|
|
||||||
// Update transition duration based on settings
|
|
||||||
if (defaults.showTime) {
|
|
||||||
// We'll set this via inline style or rely on CSS class if it matches default
|
|
||||||
// But for full control, let's set it
|
|
||||||
img.style.transitionDuration = (defaults.showTime / 1000) + 's';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (img.getAttribute('data-lazy-src')) {
|
|
||||||
observer.observe(img);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function markLoaded(img, callback) {
|
||||||
|
img.classList.add('lazy-loaded');
|
||||||
|
img.removeAttribute('data-lazy-src');
|
||||||
|
if (callback) callback();
|
||||||
|
}
|
||||||
|
|
||||||
function loadImage(img, callback) {
|
function loadImage(img, callback) {
|
||||||
var src = img.getAttribute('data-lazy-src');
|
var src = img.getAttribute('data-lazy-src');
|
||||||
if (!src) {
|
if (!src) {
|
||||||
@@ -79,37 +61,28 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img.decoding = 'async';
|
||||||
|
|
||||||
var temp = new Image();
|
var temp = new Image();
|
||||||
|
temp.decoding = 'async';
|
||||||
var onComplete = function() {
|
|
||||||
// Swap source
|
temp.onload = function() {
|
||||||
img.src = src;
|
img.src = src;
|
||||||
|
requestAnimationFrame(function() {
|
||||||
requestAnimationFrame(() => {
|
markLoaded(img, callback);
|
||||||
requestAnimationFrame(() => {
|
|
||||||
img.classList.add('lazy-loaded');
|
|
||||||
img.removeAttribute('data-lazy-src');
|
|
||||||
// Execute callback immediately after starting animation logic
|
|
||||||
if (callback) callback();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
temp.onload = onComplete;
|
|
||||||
temp.onerror = function() {
|
temp.onerror = function() {
|
||||||
// Fallback
|
|
||||||
img.src = src;
|
img.src = src;
|
||||||
requestAnimationFrame(() => {
|
markLoaded(img, callback);
|
||||||
img.classList.add('lazy-loaded');
|
|
||||||
if (callback) callback();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
temp.src = src;
|
temp.src = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadAllImages() {
|
function loadAllImages() {
|
||||||
var images = document.querySelectorAll('img.lazyload');
|
var images = getPendingImages();
|
||||||
images.forEach(function(img) {
|
images.forEach(function(img) {
|
||||||
loadImage(img);
|
loadImage(img);
|
||||||
});
|
});
|
||||||
@@ -117,5 +90,4 @@
|
|||||||
|
|
||||||
window.lazyLoadInit = init;
|
window.lazyLoadInit = init;
|
||||||
window.lazyLoadRefresh = observeImages;
|
window.lazyLoadRefresh = observeImages;
|
||||||
|
|
||||||
})();
|
})();
|
||||||
@@ -50,6 +50,16 @@ function pjax_reload() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function refreshHeatmap() {
|
||||||
|
if (typeof renderHeatmap === 'function') {
|
||||||
|
try {
|
||||||
|
renderHeatmap();
|
||||||
|
} catch (e) {
|
||||||
|
console.error('renderHeatmap error:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// pjax发送时期
|
// pjax发送时期
|
||||||
document.addEventListener("pjax:send", function () {
|
document.addEventListener("pjax:send", function () {
|
||||||
// pjax动画减少圆圈动画
|
// pjax动画减少圆圈动画
|
||||||
@@ -141,4 +151,6 @@ document.addEventListener("pjax:complete", function () {
|
|||||||
window.initSearch();
|
window.initSearch();
|
||||||
} catch(e) { console.error('initSearch error:', e); }
|
} catch(e) { console.error('initSearch error:', e); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshHeatmap();
|
||||||
});
|
});
|
||||||
@@ -1,10 +1,17 @@
|
|||||||
{{ $src := .Destination }}
|
{{ $src := .Destination }}
|
||||||
|
{{ $alt := .Text }}
|
||||||
|
{{ $width := "" }}
|
||||||
|
{{ $height := "" }}
|
||||||
|
{{ $srcset := "" }}
|
||||||
|
|
||||||
{{- if not (strings.HasPrefix $src "http") -}}
|
{{- if not (strings.HasPrefix $src "http") -}}
|
||||||
{{- $img := .Page.Resources.GetMatch $src -}}
|
{{- $img := .Page.Resources.GetMatch $src -}}
|
||||||
{{- if $img -}}
|
{{- if $img -}}
|
||||||
{{- $src = $img.RelPermalink -}}
|
{{- $src = $img.RelPermalink -}}
|
||||||
|
{{- $width = printf "%d" $img.Width -}}
|
||||||
|
{{- $height = printf "%d" $img.Height -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- $src = $src | relURL -}}
|
{{- $src = $src | relURL -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-lazy-src="{{ $src }}" alt="{{ .Text }}" class="lazyload" uk-scrollspy="cls: uk-animation-fade; delay: 200">
|
<img src="{{ $src }}" alt="{{ $alt }}" class="lazyload lazy-loaded" loading="lazy" decoding="async"{{ with $width }} width="{{ . }}"{{ end }}{{ with $height }} height="{{ . }}"{{ end }}>
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
{{ range $paginator.Pages }}
|
{{ range $paginator.Pages }}
|
||||||
<div class="post">
|
<div class="post">
|
||||||
<div class="time">{{ .Date.Format "January 2, 2006" }}</div>
|
<div class="time">{{ .Date.Format "January 2, 2006" }}</div>
|
||||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -90,6 +90,5 @@
|
|||||||
{{ end }}
|
{{ end }}
|
||||||
<!-- 评论区内容结束 -->
|
<!-- 评论区内容结束 -->
|
||||||
</div>
|
</div>
|
||||||
<script async src="/js/bsz.js"></script>
|
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
{{ range $paginator.Pages }}
|
{{ range $paginator.Pages }}
|
||||||
<div class="post">
|
<div class="post">
|
||||||
<div class="time">{{ .Date.Format "January 2, 2006" }}</div>
|
<div class="time">{{ .Date.Format "January 2, 2006" }}</div>
|
||||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
|
||||||
|
|
||||||
<!-- 计算每篇文章的发布时间与当前时间的差值 -->
|
<!-- 计算每篇文章的发布时间与当前时间的差值 -->
|
||||||
{{ $publishDate := .Date }}
|
{{ $publishDate := .Date }}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
<div id="pjax-container">
|
<div id="pjax-container" data-needs-echarts="true">
|
||||||
<div class="post-content" itemprop="articleBody" uk-scrollspy="target: > *; cls: uk-animation-slide-bottom-small; delay: 100">
|
<div class="post-content" itemprop="articleBody" uk-scrollspy="target: > *; cls: uk-animation-slide-bottom-small; delay: 100">
|
||||||
{{ .Content }}
|
{{ .Content }}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
<li data-date="{{ $year }}{{ printf "%02d" $month }}{{ .Date.Day }}">
|
<li data-date="{{ $year }}{{ printf "%02d" $month }}{{ .Date.Day }}">
|
||||||
<span class="articles_date_time">{{ .Date.Format "01/02" }}</span>
|
<span class="articles_date_time">{{ .Date.Format "01/02" }}</span>
|
||||||
<a class="a-archives" href="{{ .Permalink }}">{{ .Title }}</a>
|
<a class="a-archives" href="{{ .RelPermalink }}">{{ .Title }}</a>
|
||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
|||||||
@@ -337,6 +337,15 @@
|
|||||||
allPosts: [],
|
allPosts: [],
|
||||||
currentIndex: 0,
|
currentIndex: 0,
|
||||||
BATCH_SIZE: 10,
|
BATCH_SIZE: 10,
|
||||||
|
CACHE_KEY: 'friend-circle-v1',
|
||||||
|
CACHE_OPTIONS: {
|
||||||
|
version: 2,
|
||||||
|
softTtl: 5 * 60 * 1000,
|
||||||
|
hardTtl: 60 * 60 * 1000,
|
||||||
|
validate: function(data) {
|
||||||
|
return !!data && Array.isArray(data.posts);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
timeAgo: function (dateStr) {
|
timeAgo: function (dateStr) {
|
||||||
const date = new Date(dateStr);
|
const date = new Date(dateStr);
|
||||||
@@ -403,6 +412,74 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderEmpty: function () {
|
||||||
|
const container = document.getElementById("friend-circle-container");
|
||||||
|
if (!container) return;
|
||||||
|
container.innerHTML = '<div class="empty" style="grid-column: 1/-1; text-align:center; padding:20px;">暂无动态</div>';
|
||||||
|
},
|
||||||
|
|
||||||
|
renderError: function () {
|
||||||
|
const container = document.getElementById("friend-circle-container");
|
||||||
|
if (!container) return;
|
||||||
|
container.innerHTML = '<div class="error" style="grid-column: 1/-1; text-align:center; padding:20px; color:#d9534f;">加载失败,请稍后刷新重试</div>';
|
||||||
|
},
|
||||||
|
|
||||||
|
applyData: function (data) {
|
||||||
|
const container = document.getElementById("friend-circle-container");
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
if (!data.posts || data.posts.length === 0) {
|
||||||
|
this.renderEmpty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.FriendCircle.allPosts = data.posts;
|
||||||
|
window.fcUpdateTime = new Date(data.updated).toLocaleString();
|
||||||
|
window.FriendCircle.currentIndex = 0;
|
||||||
|
container.innerHTML = "";
|
||||||
|
window.FriendCircle.loadMore();
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchData: function () {
|
||||||
|
if (window.BrowserCache && typeof window.BrowserCache.log === 'function') {
|
||||||
|
window.BrowserCache.log('[FriendCircleCache][fetch]', {
|
||||||
|
key: window.BrowserCache ? window.BrowserCache.buildKey(window.FriendCircle.CACHE_KEY) : window.FriendCircle.CACHE_KEY,
|
||||||
|
softTtl: window.BrowserCache ? window.BrowserCache.formatDuration(window.FriendCircle.CACHE_OPTIONS.softTtl) : window.FriendCircle.CACHE_OPTIONS.softTtl,
|
||||||
|
hardTtl: window.BrowserCache ? window.BrowserCache.formatDuration(window.FriendCircle.CACHE_OPTIONS.hardTtl) : window.FriendCircle.CACHE_OPTIONS.hardTtl
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return fetch("https://rssapi.usj.cc/api/articles?limit=50")
|
||||||
|
.then(function(res) {
|
||||||
|
if (!res.ok) throw new Error("Network response was not ok");
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(function(apiData) {
|
||||||
|
const posts = (apiData.articles || []).map(function(a) {
|
||||||
|
return {
|
||||||
|
title: a.title || '',
|
||||||
|
link: a.link || '',
|
||||||
|
date: a.pubDate || '',
|
||||||
|
author: a.feedName || a.author || '',
|
||||||
|
avatar: a.favicon || '',
|
||||||
|
blogUrl: a.siteUrl || '',
|
||||||
|
image: null,
|
||||||
|
description: ''
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
posts: posts,
|
||||||
|
updated: apiData.timestamp || new Date().toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (window.BrowserCache) {
|
||||||
|
window.BrowserCache.write(window.FriendCircle.CACHE_KEY, window.FriendCircle.CACHE_OPTIONS, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
initTooltip: function() {
|
initTooltip: function() {
|
||||||
if (this.tooltipInitialized) return;
|
if (this.tooltipInitialized) return;
|
||||||
this.tooltipInitialized = true;
|
this.tooltipInitialized = true;
|
||||||
@@ -476,42 +553,35 @@
|
|||||||
if (this.isFetching) return;
|
if (this.isFetching) return;
|
||||||
this.isFetching = true;
|
this.isFetching = true;
|
||||||
|
|
||||||
// 从 RSS API 拉取按时间排序的文章
|
const cached = window.BrowserCache && window.BrowserCache.read(this.CACHE_KEY, this.CACHE_OPTIONS);
|
||||||
fetch("https://rssapi.usj.cc/api/articles?limit=50&t=" + new Date().getTime())
|
if (cached) {
|
||||||
.then(function(res) {
|
if (window.BrowserCache && typeof window.BrowserCache.log === 'function') {
|
||||||
if (!res.ok) throw new Error("Network response was not ok");
|
window.BrowserCache.log('[FriendCircleCache][render]', {
|
||||||
return res.json();
|
key: cached.key,
|
||||||
})
|
age: cached.ageText,
|
||||||
.then(function(apiData) {
|
isFresh: cached.isFresh,
|
||||||
// 将 API 格式转换为友圈格式
|
softTtl: cached.softTtlText,
|
||||||
const posts = (apiData.articles || []).map(function(a) {
|
hardTtl: cached.hardTtlText
|
||||||
return {
|
|
||||||
title: a.title || '',
|
|
||||||
link: a.link || '',
|
|
||||||
date: a.pubDate || '',
|
|
||||||
author: a.feedName || a.author || '',
|
|
||||||
avatar: a.favicon || '',
|
|
||||||
blogUrl: a.siteUrl || '',
|
|
||||||
image: null,
|
|
||||||
description: ''
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
const data = { posts: posts, updated: apiData.timestamp || new Date().toISOString() };
|
}
|
||||||
|
this.applyData(cached.data);
|
||||||
|
if (cached.isFresh) {
|
||||||
|
this.isFetching = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!data.posts || data.posts.length === 0) {
|
this.fetchData()
|
||||||
container.innerHTML = '<div class="empty" style="grid-column: 1/-1; text-align:center; padding:20px;">暂无动态</div>';
|
.then(function(data) {
|
||||||
return;
|
window.FriendCircle.applyData(data);
|
||||||
}
|
|
||||||
|
|
||||||
window.FriendCircle.allPosts = data.posts;
|
|
||||||
window.fcUpdateTime = new Date(data.updated).toLocaleString();
|
|
||||||
window.FriendCircle.currentIndex = 0;
|
|
||||||
container.innerHTML = "";
|
|
||||||
window.FriendCircle.loadMore();
|
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
console.error("Friend Circle Error:", err);
|
if (window.BrowserCache && window.BrowserCache.isDebug && window.BrowserCache.isDebug()) {
|
||||||
container.innerHTML = '<div class="error" style="grid-column: 1/-1; text-align:center; padding:20px; color:#d9534f;">加载失败,请稍后刷新重试</div>';
|
console.error("Friend Circle Error:", err);
|
||||||
|
}
|
||||||
|
if (!cached) {
|
||||||
|
window.FriendCircle.renderError();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.finally(function() {
|
.finally(function() {
|
||||||
window.FriendCircle.isFetching = false;
|
window.FriendCircle.isFetching = false;
|
||||||
@@ -519,12 +589,18 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (document.readyState === "loading") {
|
function initFriendCirclePage() {
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
if (window.FriendCircle && typeof window.FriendCircle.init === 'function') {
|
||||||
window.FriendCircle.init();
|
window.FriendCircle.init();
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('pjax:complete', initFriendCirclePage);
|
||||||
|
|
||||||
|
if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", initFriendCirclePage);
|
||||||
} else {
|
} else {
|
||||||
window.FriendCircle.init();
|
initFriendCirclePage();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -78,18 +78,96 @@
|
|||||||
var list = document.getElementById('links-list');
|
var list = document.getElementById('links-list');
|
||||||
if (!list) return;
|
if (!list) return;
|
||||||
|
|
||||||
fetch('https://rssapi.usj.cc/api/links?t=' + new Date().getTime())
|
var CACHE_KEY = 'friend-links-v1';
|
||||||
.then(function(res) { return res.json(); })
|
var CACHE_OPTIONS = {
|
||||||
.then(function(data) {
|
version: 2,
|
||||||
var links = data.links || [];
|
softTtl: 6 * 60 * 60 * 1000,
|
||||||
if (links.length === 0) return;
|
hardTtl: 24 * 60 * 60 * 1000,
|
||||||
var html = '';
|
validate: function(data) {
|
||||||
links.forEach(function(l) {
|
return !!data && Array.isArray(data.links);
|
||||||
html += '<li><a href="' + l.url + '" class="url-name" target="_blank">' + l.name + '</a><span style="margin-left: 13px;">' + (l.description || '') + '</span></li>';
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function escapeHtml(value) {
|
||||||
|
return String(value || '')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''');
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderState(message, className) {
|
||||||
|
list.innerHTML = '<li class="' + className + '">' + escapeHtml(message) + '</li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderLinks(links) {
|
||||||
|
if (!Array.isArray(links) || links.length === 0) {
|
||||||
|
renderState('暂无友链数据', 'links-empty');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
links.forEach(function(l) {
|
||||||
|
html += '<li><a href="' + escapeHtml(l.url) + '" class="url-name" target="_blank" rel="noopener noreferrer">' + escapeHtml(l.name) + '</a><span style="margin-left: 13px;">' + escapeHtml(l.description || '') + '</span></li>';
|
||||||
|
});
|
||||||
|
list.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function logCache(event, payload) {
|
||||||
|
if (window.BrowserCache && typeof window.BrowserCache.log === 'function') {
|
||||||
|
window.BrowserCache.log('[LinksCache][' + event + ']', payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchLinks() {
|
||||||
|
logCache('fetch', {
|
||||||
|
key: window.BrowserCache ? window.BrowserCache.buildKey(CACHE_KEY) : CACHE_KEY,
|
||||||
|
softTtl: window.BrowserCache ? window.BrowserCache.formatDuration(CACHE_OPTIONS.softTtl) : CACHE_OPTIONS.softTtl,
|
||||||
|
hardTtl: window.BrowserCache ? window.BrowserCache.formatDuration(CACHE_OPTIONS.hardTtl) : CACHE_OPTIONS.hardTtl
|
||||||
|
});
|
||||||
|
return fetch('https://rssapi.usj.cc/api/links')
|
||||||
|
.then(function(res) {
|
||||||
|
if (!res.ok) throw new Error('Failed to fetch links');
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(function(data) {
|
||||||
|
var links = Array.isArray(data.links) ? data.links : [];
|
||||||
|
var payload = { links: links };
|
||||||
|
window.BrowserCache.write(CACHE_KEY, CACHE_OPTIONS, payload);
|
||||||
|
return payload;
|
||||||
});
|
});
|
||||||
list.innerHTML = html;
|
}
|
||||||
|
|
||||||
|
var cached = window.BrowserCache && window.BrowserCache.read(CACHE_KEY, CACHE_OPTIONS);
|
||||||
|
if (cached) {
|
||||||
|
logCache('render', {
|
||||||
|
key: cached.key,
|
||||||
|
age: cached.ageText,
|
||||||
|
isFresh: cached.isFresh,
|
||||||
|
softTtl: cached.softTtlText,
|
||||||
|
hardTtl: cached.hardTtlText
|
||||||
|
});
|
||||||
|
renderLinks(cached.data.links);
|
||||||
|
if (cached.isFresh) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
renderState('友链加载中...', 'links-loading');
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchLinks()
|
||||||
|
.then(function(payload) {
|
||||||
|
renderLinks(payload.links);
|
||||||
})
|
})
|
||||||
.catch(function() {});
|
.catch(function(err) {
|
||||||
|
if (window.BrowserCache && window.BrowserCache.isDebug && window.BrowserCache.isDebug()) {
|
||||||
|
console.error('Links Error:', err);
|
||||||
|
}
|
||||||
|
if (!cached) {
|
||||||
|
renderState('友链加载失败,请稍后刷新重试', 'links-error');
|
||||||
|
}
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -52,19 +52,20 @@
|
|||||||
{{ $uikit := resources.Get "js/libs/uikit.min.js" }}
|
{{ $uikit := resources.Get "js/libs/uikit.min.js" }}
|
||||||
{{ $easylazyload := resources.Get "js/modules/lazyload.js" }}
|
{{ $easylazyload := resources.Get "js/modules/lazyload.js" }}
|
||||||
{{ $viewimage := resources.Get "js/libs/view-image.min.js" }}
|
{{ $viewimage := resources.Get "js/libs/view-image.min.js" }}
|
||||||
{{ $artalk := resources.Get "js/libs/Artalk.js" }}
|
|
||||||
{{ $barrage := resources.Get "js/modules/barrage.js" }}
|
{{ $barrage := resources.Get "js/modules/barrage.js" }}
|
||||||
{{ $main := resources.Get "js/main.js" }}
|
{{ $main := resources.Get "js/main.js" }}
|
||||||
{{ $mypjax := resources.Get "js/modules/mypjax.js" }}
|
{{ $mypjax := resources.Get "js/modules/mypjax.js" }}
|
||||||
{{ $nprogress := resources.Get "js/libs/nprogress.js" }}
|
{{ $nprogress := resources.Get "js/libs/nprogress.js" }}
|
||||||
{{ $message := resources.Get "js/libs/message.min.js" }}
|
{{ $message := resources.Get "js/libs/message.min.js" }}
|
||||||
{{ $echarts := resources.Get "js/libs/echarts.min.js" }}
|
|
||||||
{{ $tiaozhuan := resources.Get "js/modules/tiaozhuan.js" }}
|
{{ $tiaozhuan := resources.Get "js/modules/tiaozhuan.js" }}
|
||||||
{{ $reward := resources.Get "js/modules/reward.js" }}
|
{{ $reward := resources.Get "js/modules/reward.js" }}
|
||||||
|
{{ $echarts := resources.Get "js/libs/echarts.min.js" }}
|
||||||
|
{{ $artalk := resources.Get "js/libs/Artalk.js" }}
|
||||||
|
|
||||||
{{/* Modules */}}
|
{{/* Modules */}}
|
||||||
{{ $utils := resources.Get "js/modules/utils.js" }}
|
{{ $utils := resources.Get "js/modules/utils.js" }}
|
||||||
{{ $loader := resources.Get "js/modules/loader.js" }}
|
{{ $loader := resources.Get "js/modules/loader.js" }}
|
||||||
|
{{ $cache := resources.Get "js/modules/cache.js" }}
|
||||||
{{ $search := resources.Get "js/modules/search.js" }}
|
{{ $search := resources.Get "js/modules/search.js" }}
|
||||||
{{ $floatingTools := resources.Get "js/modules/floating-tools.js" }}
|
{{ $floatingTools := resources.Get "js/modules/floating-tools.js" }}
|
||||||
{{ $paragraphComments := resources.Get "js/modules/paragraph-comments.js" }}
|
{{ $paragraphComments := resources.Get "js/modules/paragraph-comments.js" }}
|
||||||
@@ -72,9 +73,9 @@
|
|||||||
{{ $artalkModule := resources.Get "js/modules/artalk.js" }}
|
{{ $artalkModule := resources.Get "js/modules/artalk.js" }}
|
||||||
{{ $pjaxLib := resources.Get "js/libs/pjax.js" }}
|
{{ $pjaxLib := resources.Get "js/libs/pjax.js" }}
|
||||||
|
|
||||||
{{ $scripts := slice $iconfont $lightgallery $uikit $easylazyload $viewimage $artalk $barrage $utils $loader $search $floatingTools $paragraphComments $infiniteScroll $artalkModule $nprogress $pjaxLib $main $mypjax $message $echarts $tiaozhuan $reward | resources.Concat "js/bundle.js" | resources.Minify | resources.Fingerprint }}
|
{{ $scripts := slice $iconfont $lightgallery $uikit $easylazyload $viewimage $barrage $utils $loader $cache $search $floatingTools $paragraphComments $infiniteScroll $artalkModule $nprogress $pjaxLib $main $mypjax $message $tiaozhuan $reward $echarts $artalk | resources.Concat "js/bundle.js" | resources.Minify | resources.Fingerprint }}
|
||||||
|
|
||||||
<script src="{{ $scripts.RelPermalink }}"></script>
|
<script defer src="{{ $scripts.RelPermalink }}"></script>
|
||||||
<script>
|
<script>
|
||||||
// Global configuration from Hugo
|
// Global configuration from Hugo
|
||||||
window.enableInfiniteScroll = {{ .Site.Params.infiniteScroll.enable | default false }};
|
window.enableInfiniteScroll = {{ .Site.Params.infiniteScroll.enable | default false }};
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
<head>
|
|
||||||
<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 -->
|
<!-- SEO & Meta Tags -->
|
||||||
<meta name="description" content="{{ if .IsHome }}{{ .Site.Params.description }}{{ else }}{{ .Description | default .Summary | plainify | truncate 160 }}{{ end }}" />
|
<meta name="description" content="{{ if .IsHome }}{{ .Site.Params.description }}{{ else }}{{ .Description | default .Summary | plainify | truncate 160 }}{{ end }}" />
|
||||||
<link rel="canonical" href="{{ .Permalink }}" />
|
<link rel="canonical" href="{{ .RelPermalink | absURL }}" />
|
||||||
|
|
||||||
{{- $keywords := slice "大学" "教程" "blog" "优世界" "优设计" "博客" "大学生博客" "生活" "文案" -}}
|
{{- $keywords := slice "大学" "教程" "blog" "优世界" "优设计" "博客" "大学生博客" "生活" "文案" -}}
|
||||||
{{- if .Params.tags -}}
|
{{- if .Params.tags -}}
|
||||||
@@ -72,6 +71,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<!-- Preload Fonts -->
|
<!-- Preload Fonts -->
|
||||||
<link rel="preload" href="{{ "font/zql-v2.woff2" | relURL }}" as="font" type="font/woff2" crossorigin>
|
<link rel="preload" href="{{ "font/zql-v2.woff2" | relURL }}" as="font" type="font/woff2" crossorigin>
|
||||||
|
<link rel="preload" href="{{ "font/remixicon.woff2" | relURL }}" as="font" type="font/woff2" crossorigin>
|
||||||
|
|
||||||
<!-- Site Configuration -->
|
<!-- Site Configuration -->
|
||||||
<script>
|
<script>
|
||||||
@@ -98,12 +98,14 @@
|
|||||||
{{ $remixicon := resources.Get "css/libs/remixicon.css" }}
|
{{ $remixicon := resources.Get "css/libs/remixicon.css" }}
|
||||||
{{ $uikit := resources.Get "css/libs/uikit.min.css" }}
|
{{ $uikit := resources.Get "css/libs/uikit.min.css" }}
|
||||||
{{ $nprogress := resources.Get "css/libs/nprogress.min.css" }}
|
{{ $nprogress := resources.Get "css/libs/nprogress.min.css" }}
|
||||||
{{ $artalk := resources.Get "css/libs/Artalk.css" }}
|
|
||||||
{{ $message := resources.Get "css/libs/message.min.css" }}
|
{{ $message := resources.Get "css/libs/message.min.css" }}
|
||||||
{{ $main := resources.Get "css/main.css" }}
|
{{ $main := resources.Get "css/main.css" }}
|
||||||
|
|
||||||
{{ $style := slice $normalize $remixicon $uikit $nprogress $artalk $message $main | resources.Concat "css/style.css" | resources.Minify | resources.Fingerprint }}
|
{{ $style := slice $normalize $remixicon $uikit $nprogress $message $main | resources.Concat "css/style.css" | resources.Minify | resources.Fingerprint }}
|
||||||
|
{{ $artalk := resources.Get "css/libs/Artalk.css" | resources.Minify | resources.Fingerprint }}
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{ $style.RelPermalink }}">
|
<link rel="stylesheet" href="{{ $style.RelPermalink }}">
|
||||||
|
<link rel="stylesheet" href="{{ $artalk.RelPermalink }}">
|
||||||
|
|
||||||
{{- if and .Site.Params.style.enableBackgroundImage .Site.Params.style.backgroundImageUrl -}}
|
{{- if and .Site.Params.style.enableBackgroundImage .Site.Params.style.backgroundImageUrl -}}
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="header-top">
|
<div class="header-top">
|
||||||
<div class="header-avatar load-memos-editor" id="theme-toggle-avatar">
|
<div class="header-avatar load-memos-editor" id="theme-toggle-avatar">
|
||||||
<img src="{{ .Site.Params.author.avatar }}" class="blog-img" width="80" height="80" alt="{{ .Site.Title }}" />
|
<img src="{{ .Site.Params.author.avatar }}" class="blog-img" width="80" height="80" alt="{{ .Site.Title }}" decoding="async" fetchpriority="high" />
|
||||||
<div class="avatar-theme-tip">
|
<div class="avatar-theme-tip">
|
||||||
点击头像切换昼夜
|
点击头像切换昼夜
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in new issue
Block a user