Files
blog/posts/ad244066/index.html
T
2026-07-19 16:12:13 +08:00

1728 lines
224 KiB
HTML

<!DOCTYPE html><html lang="zh-CN"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="description" content="这段文字看起来是一个部署教程,主要是关于如何在服务器上部署一个名为“Moments”的应用,并将其与网站集成。以下是对这段文字的概括: 1. 介绍了硬件和软件的要求,包括服务器、域名、Docker环境和反向代理工具(如Nginx)。 2. 提供了Moments应用的部署方法,包括使用docker-compose进行部署和配置Nginx反向代理。 3. 介绍了如何在前端集成Moments应用,包括引入必要的CSS和JS文件,以及创建一个新的页面来显示Moments的内容。 需要注意的是,这段文字中的一些链接和代码可能已经过时或者不适用于所有场景,建议在实际操作时参考最新的官方"><meta name="author" content="biss"><meta name="keywords" content="建站手札, 网站"><link rel="canonical" href="https://blog.biss.click/posts/ad244066/"><link rel="alternate" type="application/rss+xml" title="Bi's Blog RSS" href="https://blog.biss.click/rss.xml"><meta property="og:site_name" content="Bi's Blog"><meta property="og:locale" content="zh_CN"><meta property="og:type" content="article"><meta property="og:title" content="配置说说页面 | Bi's Blog"><meta property="og:description" content="这段文字看起来是一个部署教程,主要是关于如何在服务器上部署一个名为“Moments”的应用,并将其与网站集成。以下是对这段文字的概括: 1. 介绍了硬件和软件的要求,包括服务器、域名、Docker环境和反向代理工具(如Nginx)。 2. 提供了Moments应用的部署方法,包括使用docker-compose进行部署和配置Nginx反向代理。 3. 介绍了如何在前端集成Moments应用,包括引入必要的CSS和JS文件,以及创建一个新的页面来显示Moments的内容。 需要注意的是,这段文字中的一些链接和代码可能已经过时或者不适用于所有场景,建议在实际操作时参考最新的官方"><meta property="og:url" content="https://blog.biss.click/posts/ad244066/"><meta property="og:image" content="https://pic.biss.click/image/0f3b8150-af77-426f-afc1-36df5ab27b36.webp"><meta property="og:image:alt" content="配置说说页面"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="配置说说页面 | Bi's Blog"><meta name="twitter:description" content="这段文字看起来是一个部署教程,主要是关于如何在服务器上部署一个名为“Moments”的应用,并将其与网站集成。以下是对这段文字的概括: 1. 介绍了硬件和软件的要求,包括服务器、域名、Docker环境和反向代理工具(如Nginx)。 2. 提供了Moments应用的部署方法,包括使用docker-compose进行部署和配置Nginx反向代理。 3. 介绍了如何在前端集成Moments应用,包括引入必要的CSS和JS文件,以及创建一个新的页面来显示Moments的内容。 需要注意的是,这段文字中的一些链接和代码可能已经过时或者不适用于所有场景,建议在实际操作时参考最新的官方"><meta name="twitter:image" content="https://pic.biss.click/image/0f3b8150-af77-426f-afc1-36df5ab27b36.webp"><meta property="article:published_time" content="2025-08-10T08:25:39.000Z"><meta property="article:modified_time" content="2025-08-10T08:25:39.000Z"><meta property="article:author" content="biss"><meta property="article:tag" content="建站手札"><meta property="article:tag" content="网站"><script type="application/ld+json">{"@context":"https://schema.org","@type":"BlogPosting","headline":"配置说说页面","description":"这段文字看起来是一个部署教程,主要是关于如何在服务器上部署一个名为“Moments”的应用,并将其与网站集成。以下是对这段文字的概括: 1. 介绍了硬件和软件的要求,包括服务器、域名、Docker环境和反向代理工具(如Nginx)。 2. 提供了Moments应用的部署方法,包括使用docker-compose进行部署和配置Nginx反向代理。 3. 介绍了如何在前端集成Moments应用,包括引入必要的CSS和JS文件,以及创建一个新的页面来显示Moments的内容。 需要注意的是,这段文字中的一些链接和代码可能已经过时或者不适用于所有场景,建议在实际操作时参考最新的官方","image":["https://pic.biss.click/image/0f3b8150-af77-426f-afc1-36df5ab27b36.webp"],"datePublished":"2025-08-10T08:25:39.000Z","dateModified":"2025-08-10T08:25:39.000Z","wordCount":1614,"inLanguage":"zh-CN","mainEntityOfPage":{"@type":"WebPage","@id":"https://blog.biss.click/posts/ad244066/"},"author":{"@type":"Person","name":"biss","url":"https://github.com/bishshi"},"publisher":{"@type":"Person","name":"biss","image":"https://free.picui.cn/free/2025/08/10/689845496a283.png"},"keywords":"建站手札, 网站","articleSection":"建站手札","isPartOf":{"@type":"CreativeWorkSeries","name":"webcustom"}}</script><link rel="icon" href="/images/Bi.ico"><link rel="manifest" href="/manifest.webmanifest"><link rel="apple-touch-icon" href="/images/apple-touch-icon.png"><meta name="theme-color" content="#f7f5ef" media="(prefers-color-scheme: light)"><meta name="theme-color" content="#0b1014" media="(prefers-color-scheme: dark)"><script defer src="https://umami.biss.click/script.js" data-website-id="3d97b310-b241-4fc6-bc9c-68e317fc7d42"></script><script>window.SITE_CONFIG = {"site":{"url":"https://blog.biss.click","name":"Bi's Blog","description":"Personal blog by biss.","language":"zh-CN","domain":"blog.biss.click","slogan":"好奇心转化为代码的空间。","startTime":"2025-01-01T00:00:00+08:00","copyrightStartYear":2025,"license":"内容采用 CC BY-NC-SA 4.0 协议"},"author":{"name":"biss","email":"bishsh2006@gmail.com","github":"https://github.com/bishshi","avatar":"https://free.picui.cn/free/2025/08/10/689845496a283.png"},"comments":{"envId":"https://comment.biss.click","region":"","script":"https://cdn.jsdelivr.net/npm/twikoo@1.7.7/dist/twikoo.min.js"},"analytics":{"umami":{"script":"https://umami.biss.click/script.js","websiteId":"3d97b310-b241-4fc6-bc9c-68e317fc7d42","statsEndpoint":"https://blogumami.biss.click"}},"talks":{"apiUrl":"https://mm.biss.click/api/echo/page","pageSize":30,"homeLimit":6,"cacheKey":"talksCache","cacheTimeKey":"talksCacheTime","cacheDurationMs":1800000,"fallbackAvatar":"https://free.picui.cn/free/2025/08/10/689845496a283.png"},"search":{"apiKey":"2uxQzk7eD2GBCljdSmIiuU3ause7UK9n","server":{"host":"typesense.biss.click","port":"443","protocol":"https"},"indexName":"blogs","searchParams":{"query_by":"title,content","highlight_full_fields":"title,content","per_page":8,"num_typos":1,"typo_tokens_threshold":1,"prefix":true},"ui":{"maxRetries":10,"retryDelay":100,"animationDuration":300,"maxInitRetries":30,"placeholder":"输入关键词寻找故事..."}},"externalLinks":{"waitSeconds":10,"whitelist":["blog.biss.click","biss.click","github.com","localhost","127.0.0.1"]}};</script><script>
(() => {
const storageKey = 'site-theme';
const media = window.matchMedia('(prefers-color-scheme: dark)');
const getSystemTheme = () => (media.matches ? 'dark' : 'light');
const getSavedTheme = () => {
try {
const theme = localStorage.getItem(storageKey);
return theme === 'dark' || theme === 'light' ? theme : null;
} catch {
return null;
}
};
document.documentElement.dataset.theme = getSavedTheme() || getSystemTheme();
})();
</script><link rel="stylesheet" href="https://cdn.jsdmirror.com/npm/instantsearch.css/themes/reset-min.css"><link rel="stylesheet" href="https://cdn.jsdmirror.com/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css"><link rel="stylesheet" href="https://cdn.jsdmirror.com/npm/@fortawesome/fontawesome-free@6.7.2/css/all.min.css"><title>配置说说页面 | Bi&#39;s Blog</title><link rel="stylesheet" href="/_astro/BaseLayout.DvPRLM9I.css"></head> <body> <header class="site-header"> <nav class="nav"> <a class="brand" href="/" aria-label="Bi's Blog 首页"><span>biss</span><i>.log</i></a> <button class="nav-menu-toggle" type="button" aria-label="打开菜单" aria-expanded="false" data-nav-toggle> <i class="fa-solid fa-bars nav-menu-open" aria-hidden="true"></i> <i class="fa-solid fa-xmark nav-menu-close" aria-hidden="true"></i> </button> <div class="nav-drawer-backdrop" data-nav-backdrop></div> <div class="nav-menu" data-nav-menu> <div class="nav-links nav-center"> <a href="/archives/"><i class="fa-solid fa-box-archive nav-icon" aria-hidden="true"></i><span>归档</span></a><a href="/categories/"><i class="fa-solid fa-folder-open nav-icon" aria-hidden="true"></i><span>分类</span></a><a href="/tags/"><i class="fa-solid fa-tags nav-icon" aria-hidden="true"></i><span>标签</span></a><a href="/shuoshuo/"><i class="fa-regular fa-comments nav-icon" aria-hidden="true"></i><span>说说</span></a><a href="/about/"><i class="fa-solid fa-heart nav-icon" aria-hidden="true"></i><span>关于</span></a><a href="/link/"><i class="fa-solid fa-link nav-icon" aria-hidden="true"></i><span>友链</span></a> </div> <div class="nav-links nav-actions"> <button class="nav-random" type="button" onclick="randomPost()" aria-label="前往随机文章" title="前往随机文章"> <i class="fa-solid fa-shuffle nav-icon" aria-hidden="true"></i> <span>随机文章</span> </button> <button class="nav-search search-typesense-trigger" type="button" aria-label="搜索" title="搜索"> <i class="fa-solid fa-magnifying-glass nav-icon" aria-hidden="true"></i> <span>搜索</span> </button> <button class="nav-console" type="button" aria-label="打开中控台" title="中控台" data-console-open> <i class="fa-solid fa-gauge-high nav-icon" aria-hidden="true"></i> <span>中控台</span> </button> <button class="theme-toggle" type="button" aria-label="切换夜间模式" title="切换夜间模式" data-theme-toggle> <i class="fa-solid fa-sun theme-toggle-sun nav-icon" aria-hidden="true"></i> <i class="fa-solid fa-moon theme-toggle-moon nav-icon" aria-hidden="true"></i> </button> </div> </div> </nav> </header> <div class="control-console" data-console-modal aria-hidden="true"> <div class="control-console-backdrop" data-console-close></div> <section class="control-console-panel" role="dialog" aria-modal="true" aria-labelledby="control-console-title" tabindex="-1"> <header class="control-console-head"> <div> <p>CONTROL CENTER</p> <h2 id="control-console-title">中控台</h2> </div> <button class="control-console-close" type="button" aria-label="关闭中控台" title="关闭" data-console-close> <i class="fa-solid fa-xmark" aria-hidden="true"></i> </button> </header> <div class="control-console-grid"> <a class="control-site-card" href="https://biss.click" target="_blank" rel="noreferrer"> <i class="fa-solid fa-house-chimney" aria-hidden="true"></i> <span> <strong>主站入口</strong> <em>个人主页与常用入口集合</em> </span> <small>biss.click</small> </a><a class="control-site-card" href="https://mm.biss.click" target="_blank" rel="noreferrer"> <i class="fa-regular fa-comments" aria-hidden="true"></i> <span> <strong>说说动态</strong> <em>短句、碎片记录和近况更新</em> </span> <small>mm.biss.click</small> </a><a class="control-site-card" href="https://comment.biss.click" target="_blank" rel="noreferrer"> <i class="fa-solid fa-message" aria-hidden="true"></i> <span> <strong>评论系统</strong> <em>Twikoo 评论服务与访客互动</em> </span> <small>comment.biss.click</small> </a><a class="control-site-card" href="https://umami.biss.click" target="_blank" rel="noreferrer"> <i class="fa-solid fa-chart-line" aria-hidden="true"></i> <span> <strong>站点统计</strong> <em>Umami 访问统计与站点数据</em> </span> <small>umami.biss.click</small> </a> </div> <div class="control-console-info" aria-label="站点信息"> <section> <span>当前站点</span> <strong>blog.biss.click</strong> </section> <section> <span>站点作者</span> <strong>biss</strong> </section> <section> <span>运行起点</span> <strong>2025-01-01</strong> </section> </div> </section> </div> <main> <div class="reading-progress" aria-hidden="true"><span data-reading-progress></span></div> <aside class="reading-resume" data-reading-resume hidden aria-live="polite"> <div class="reading-resume-icon" aria-hidden="true"><i class="fa-solid fa-book-open"></i></div> <div> <strong>继续上次阅读?</strong> <p>你上次读到了 <span data-reading-resume-percent>--</span></p> </div> <div class="reading-resume-actions"> <button type="button" data-reading-continue>继续阅读</button> <button type="button" data-reading-restart>从头开始</button> </div> </aside> <section class="post-layout"> <article class="article post-article"> <header class="article-header article-header-cover"> <img class="article-header-cover-img" src="https://pic.biss.click/image/0f3b8150-af77-426f-afc1-36df5ab27b36.webp" alt="" loading="eager" decoding="async"> <div class="article-header-content"> <div class="article-date-line"> <time datetime="2025-08-10T08:25:39.000Z">发布于 2025/08/10</time> </div> <h1>配置说说页面</h1> <div class="article-hero-meta" aria-label="文章信息"> <span>发布于 2025/08/10</span> <a href="/categories/site-notes/">建站手札</a> <span>总字数:1.6k</span> <span>阅读时长:5 分钟</span> </div> </div> </header> <section class="article-summary-card" aria-label="文章导读"> <div class="article-summary-header"> <span class="article-summary-brand"> <span class="article-summary-icon" aria-hidden="true"></span>
文章导读
</span> <span class="article-summary-model">摘要由 Qwen 生成</span> </div> <p class="article-summary-content"> <span class="article-summary-text">这段文字看起来是一个部署教程,主要是关于如何在服务器上部署一个名为“Moments”的应用,并将其与网站集成。以下是对这段文字的概括: 1. 介绍了硬件和软件的要求,包括服务器、域名、Docker环境和反向代理工具(如Nginx)。 2. 提供了Moments应用的部署方法,包括使用docker-compose进行部署和配置Nginx反向代理。 3. 介绍了如何在前端集成Moments应用,包括引入必要的CSS和JS文件,以及创建一个新的页面来显示Moments的内容。 需要注意的是,这段文字中的一些链接和代码可能已经过时或者不适用于所有场景,建议在实际操作时参考最新的官方</span> </p> </section> <section class="post-series" aria-labelledby="post-series-title"> <header class="post-series-head"> <div> <span>ARTICLE SERIES</span> <h2 id="post-series-title">博客定制手记</h2> </div> <strong>第 1 / 14 篇</strong> </header> <ol class="post-series-list"> <li class="is-current"> <a href="/posts/ad244066/" aria-current="page"> <span>01</span> <strong>配置说说页面</strong> </a> </li><li> <a href="/posts/da17d00/"> <span>02</span> <strong>在侧边栏中添加欢迎信息</strong> </a> </li><li> <a href="/posts/8bdb35fb/"> <span>03</span> <strong>自定义右键菜单</strong> </a> </li><li> <a href="/posts/a6ab0925/"> <span>04</span> <strong>利用插件自定义页脚菜单</strong> </a> </li><li> <a href="/posts/41b9aff7/"> <span>05</span> <strong>博客添加AI总结</strong> </a> </li><li> <a href="/posts/b5866b9e/"> <span>06</span> <strong>利用 SiteMap 随机访问站内页面</strong> </a> </li><li> <a href="/posts/3e61a389/"> <span>07</span> <strong>自定义导航栏</strong> </a> </li><li> <a href="/posts/33249733/"> <span>08</span> <strong>自定义分类条</strong> </a> </li><li> <a href="/posts/c6143ad3/"> <span>09</span> <strong>自定义页脚(新)</strong> </a> </li><li> <a href="/posts/ce1ec3fe/"> <span>10</span> <strong>使用GitHub推送Hexo到服务器</strong> </a> </li><li> <a href="/posts/5ed2f1e6/"> <span>11</span> <strong>在侧边栏添加日历和倒计时</strong> </a> </li><li> <a href="/posts/b5601a7e/"> <span>12</span> <strong>自定义字体</strong> </a> </li><li> <a href="/posts/f287c563/"> <span>13</span> <strong>添加typesense搜索</strong> </a> </li><li> <a href="/posts/7e921903/"> <span>14</span> <strong>添加网站左上角菜单</strong> </a> </li> </ol> <nav class="post-series-nav" aria-label="系列文章导航"> <span></span> <a href="/posts/da17d00/" rel="next"><span>下一篇</span><strong>在侧边栏中添加欢迎信息</strong></a> </nav> </section> <aside class="butterfly-note butterfly-note--warning article-outdated-note" aria-label="文章时效性提示" data-freshness-at="2025-08-10T08:25:39.000Z" data-has-new-version="false" hidden> <i class="fa-solid fa-triangle-exclamation" aria-hidden="true"></i> <div class="butterfly-note__content"> <p>
注意:本文最后维护于 2025/08/10,距今已超过一年,部分内容可能已经过时,请结合最新资料判断。
</p> </div> </aside> <div class="prose" data-toc="[{&quot;depth&quot;:1,&quot;text&quot;:&quot;前期要求&quot;,&quot;id&quot;:&quot;前期要求&quot;},{&quot;depth&quot;:2,&quot;text&quot;:&quot;硬件要求&quot;,&quot;id&quot;:&quot;硬件要求&quot;},{&quot;depth&quot;:2,&quot;text&quot;:&quot;软件要求&quot;,&quot;id&quot;:&quot;软件要求&quot;},{&quot;depth&quot;:1,&quot;text&quot;:&quot;介绍与展示&quot;,&quot;id&quot;:&quot;介绍与展示&quot;},{&quot;depth&quot;:1,&quot;text&quot;:&quot;部署教程&quot;,&quot;id&quot;:&quot;部署教程&quot;},{&quot;depth&quot;:2,&quot;text&quot;:&quot;Moments部署&quot;,&quot;id&quot;:&quot;moments部署&quot;},{&quot;depth&quot;:3,&quot;text&quot;:&quot;Compose部署&quot;,&quot;id&quot;:&quot;compose部署&quot;},{&quot;depth&quot;:3,&quot;text&quot;:&quot;Nginx修改&quot;,&quot;id&quot;:&quot;nginx修改&quot;},{&quot;depth&quot;:2,&quot;text&quot;:&quot;前端实现&quot;,&quot;id&quot;:&quot;前端实现&quot;},{&quot;depth&quot;:1,&quot;text&quot;:&quot;参考内容&quot;,&quot;id&quot;:&quot;参考内容&quot;}]"> <div class="butterfly-note butterfly-note--warning butterfly-note--simple"><i class="fa-solid fa-circle-info" aria-hidden="true"></i><div class="butterfly-note__content"><p>注意:本文为早期 Hexo / Butterfly 魔改记录,本站现已迁移到 Astro,相关代码、路径或插件可能已经失效,仅作历史参考。</p></div></div>
又开始折腾啦,这次把说说页面加上,改用moments项目的api
<a class="hexo-link-card" href="https://github.com/kingwrcy/moments" target="_blank" rel="external nofollow noopener noreferrer">
<span class="hexo-link-card__icon" aria-hidden="true">G</span>
<span class="hexo-link-card__body">
<strong>Moments 极简朋友圈</strong>
<span>githun · github.com</span>
</span>
</a>
<h1 id="前期要求">前期要求</h1>
<h2 id="硬件要求">硬件要求</h2>
<ol>
<li>一台服务器</li>
<li>一个可自主解析的域名</li>
</ol>
<h2 id="软件要求">软件要求</h2>
<ol>
<li>docker环境</li>
<li>反向代理工具(本文以Nginx为例)</li>
</ol>
<h1 id="介绍与展示">介绍与展示</h1>
<p>这里先给大家展示一下最终的效果,注意该教程可能仅适合部分主题,如果出现主题不适配的情况请自行适配,这里以本站主题 <code>Hexo-theme-butterfly</code>为基础进行修改:</p>
<ol>
<li>
说说页面:
<a class="hexo-link-card" href="https://blog.biss.click" target="_blank" rel="external nofollow noopener noreferrer">
<span class="hexo-link-card__icon" aria-hidden="true"></span>
<span class="hexo-link-card__body">
<strong>我的说说</strong>
<span>胡言乱语ing。。。 · blog.biss.click</span>
</span>
</a>
</li>
<li>
轻量朋友圈
<a class="hexo-link-card" href="https://mm.biss.blog" target="_blank" rel="external nofollow noopener noreferrer">
<span class="hexo-link-card__icon" aria-hidden="true"></span>
<span class="hexo-link-card__body">
<strong>朋友圈</strong>
<span>依旧胡言乱语 · mm.biss.blog</span>
</span>
</a>
</li>
<li>功能说明</li>
</ol>
<p>Moments作为一个轻量朋友圈,其功能都是分享上的部分,如下所示:</p>
<ul>
<li>分享:链接,图片,音乐,视频,书籍,电影</li>
<li>信息:自定义位置,自定义标签,是否公开</li>
<li>页面:Markdown渲染,编辑说说,删除说说,暗夜模式,自定义图标,信息,CSS及JS代码</li>
<li>功能:S3存储,文件查询,多用户注册,点赞,评论,API</li>
</ul>
<p>简单介绍完毕,下面我就来教大家如何进行部署!</p>
<h1 id="部署教程">部署教程</h1>
<h2 id="moments部署">Moments部署</h2>
<h3 id="compose部署">Compose部署</h3>
<p>官方给予了很完善的教程,这里我仅仅简单介绍一下 <code>docker-compose</code>部署的方式,如果你想以源码等其他方式进行部署,请查看文章开头部分的 <code>github</code>地址进行查阅。</p>
<p>首先,在服务器任意位置创建文件:<code>docker-compose.yaml</code>,填入以下内容:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#B392F0">version:</span><span style="color:#9ECBFF"> '3'</span></span>
<span class="line"><span style="color:#B392F0">services:</span></span>
<span class="line"><span style="color:#B392F0"> moments:</span></span>
<span class="line"><span style="color:#B392F0"> image:</span><span style="color:#9ECBFF"> kingwrcy/moments:latest</span></span>
<span class="line"><span style="color:#B392F0"> container_name:</span><span style="color:#9ECBFF"> moments</span></span>
<span class="line"><span style="color:#B392F0"> restart:</span><span style="color:#9ECBFF"> always</span></span>
<span class="line"><span style="color:#B392F0"> environment:</span></span>
<span class="line"><span style="color:#B392F0"> port:</span><span style="color:#79B8FF"> 3000</span></span>
<span class="line"><span style="color:#B392F0"> JWT_KEY:</span><span style="color:#9ECBFF"> "自己随便生成点字符串"</span></span>
<span class="line"><span style="color:#B392F0"> ENABLE_SWAGGER:</span><span style="color:#9ECBFF"> "true"</span></span>
<span class="line"><span style="color:#B392F0"> CORS_ORIGIN:</span><span style="color:#6A737D"> # 填写跨域域名</span></span>
<span class="line"><span style="color:#B392F0"> ports:</span></span>
<span class="line"><span style="color:#B392F0"> -</span><span style="color:#9ECBFF"> "3000:3000"</span><span style="color:#6A737D"> # 自行换端口,换前面的,后面的3000不要动</span></span>
<span class="line"><span style="color:#B392F0"> volumes:</span></span>
<span class="line"><span style="color:#B392F0"> -</span><span style="color:#9ECBFF"> ./opt/data:/app/data</span></span>
<span class="line"><span style="color:#6A737D"> # - ./data/localtime:/etc/localtime:ro</span></span>
<span class="line"><span style="color:#6A737D"> # - ./data/timezone:/etc/timezone:ro</span></span></code></pre>
<p>注意文件,我将 <code>/opt/</code>文件夹(当然可以改成其他的)下的 <code>/data</code>文件夹挂载了进去,数据都会在里面,迁移时仅需整体打包到新服务器即可。然后执行以下两条命令,后续需要升级也仅需要执行这两个命令:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#B392F0">docker-compose</span><span style="color:#9ECBFF"> pull</span></span>
<span class="line"><span style="color:#B392F0">docker-compose</span><span style="color:#9ECBFF"> up</span><span style="color:#79B8FF"> -d</span></span></code></pre>
<p>如果网络环境不佳,可尝试替换 <code>docker</code>源,可以自行查找</p>
<p>通过反向代理将其添加到某个域名中,这里就不再多说了,各大面板都有极其完备的反代文档。</p>
<h3 id="nginx修改">Nginx修改</h3>
<p><code>Moments</code>在跨域 <code>docker-compose</code>文件中可以配置,所以不必进行此步</p>
<p>网站目录</p>
<p>返回到上一级目录,也就是域名名称的文件夹下,找到 <code>Proxy</code>文件夹,编辑里面的 <code>root.conf</code>文件为如下内容:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#6A737D">#代理配置</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">location</span><span style="color:#9ECBFF"> /</span><span style="color:#9ECBFF"> {</span></span>
<span class="line"><span style="color:#6A737D"> # 跨域设置</span></span>
<span class="line"><span style="color:#B392F0"> add_header</span><span style="color:#9ECBFF"> Access-Control-Allow-Origin</span><span style="color:#79B8FF"> *</span><span style="color:#E1E4E8">; </span><span style="color:#6A737D"># 允许所有域名访问,你也可以指定具体域名</span></span>
<span class="line"><span style="color:#B392F0"> add_header</span><span style="color:#9ECBFF"> Access-Control-Allow-Methods</span><span style="color:#9ECBFF"> 'GET, POST, PUT, DELETE, OPTIONS'</span><span style="color:#E1E4E8">; </span><span style="color:#6A737D"># 允许的 HTTP 方法</span></span>
<span class="line"><span style="color:#B392F0"> add_header</span><span style="color:#9ECBFF"> Access-Control-Allow-Headers</span><span style="color:#9ECBFF"> 'Origin, X-Requested-With, Content-Type, Accept, Authorization'</span><span style="color:#E1E4E8">; </span><span style="color:#6A737D"># 允许的请求头</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D"> # 处理 OPTIONS 请求,预检请求</span></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> ($request_method = </span><span style="color:#9ECBFF">'OPTIONS'</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#B392F0"> add_header</span><span style="color:#9ECBFF"> Access-Control-Allow-Origin</span><span style="color:#79B8FF"> *</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0"> add_header</span><span style="color:#9ECBFF"> Access-Control-Allow-Methods</span><span style="color:#9ECBFF"> 'GET, POST, PUT, DELETE, OPTIONS'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0"> add_header</span><span style="color:#9ECBFF"> Access-Control-Allow-Headers</span><span style="color:#9ECBFF"> 'Origin, X-Requested-With, Content-Type, Accept, Authorization'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0"> add_header</span><span style="color:#9ECBFF"> Access-Control-Max-Age</span><span style="color:#79B8FF"> 1728000</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0"> add_header</span><span style="color:#9ECBFF"> Content-Type</span><span style="color:#9ECBFF"> 'text/plain charset=UTF-8'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0"> add_header</span><span style="color:#9ECBFF"> Content-Length</span><span style="color:#79B8FF"> 0</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#79B8FF"> 204</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D"> # 原代理设置</span></span>
<span class="line"><span style="color:#B392F0"> proxy_pass</span><span style="color:#9ECBFF"> http://127.0.0.1:3003</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_set_header</span><span style="color:#9ECBFF"> Host</span><span style="color:#E1E4E8"> $host;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_set_header</span><span style="color:#9ECBFF"> X-Real-IP</span><span style="color:#E1E4E8"> $remote_addr;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_set_header</span><span style="color:#9ECBFF"> X-Forwarded-For</span><span style="color:#E1E4E8"> $proxy_add_x_forwarded_for;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_set_header</span><span style="color:#9ECBFF"> REMOTE-HOST</span><span style="color:#E1E4E8"> $remote_addr;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_set_header</span><span style="color:#9ECBFF"> Upgrade</span><span style="color:#E1E4E8"> $http_upgrade;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_set_header</span><span style="color:#9ECBFF"> Connection</span><span style="color:#E1E4E8"> $http_connection;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_set_header</span><span style="color:#9ECBFF"> X-Forwarded-Proto</span><span style="color:#E1E4E8"> $scheme;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_http_version</span><span style="color:#79B8FF"> 1.1</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0"> add_header</span><span style="color:#9ECBFF"> X-Cache</span><span style="color:#E1E4E8"> $upstream_cache_status;</span></span>
<span class="line"><span style="color:#B392F0"> add_header</span><span style="color:#9ECBFF"> Cache-Control</span><span style="color:#9ECBFF"> no-cache</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_ssl_server_name</span><span style="color:#9ECBFF"> off</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_ssl_name</span><span style="color:#E1E4E8"> $proxy_host;</span></span>
<span class="line"><span style="color:#B392F0"> add_header</span><span style="color:#9ECBFF"> Strict-Transport-Security</span><span style="color:#9ECBFF"> "max-age=31536000"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span></code></pre>
<p>下面是原代理设置,可以仅仅复制上面部分内容,下面保持不变,注意端口不要出问题。</p>
<h2 id="前端实现">前端实现</h2>
<p>由于该项目利用了MetingJS和APlayer,所以请提前引入这两个包,Hexo-theme-butterfly中虽然有内置的两个包,仅需修改配置文件即可开启,但是版本比较老,这里我建议自行引入最新版本,在配置中引入以下文件,注意css和js应该是分开引入的:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#F97583">&#x3C;</span><span style="color:#E1E4E8">link rel</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"stylesheet"</span><span style="color:#E1E4E8"> href</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"https://fastly.jsdelivr.net/npm/aplayer/dist/APlayer.min.css"</span><span style="color:#E1E4E8"> media</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"all"</span><span style="color:#E1E4E8"> onload</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"this.media="all""</span><span style="color:#F97583">></span></span>
<span class="line"><span style="color:#F97583">&#x3C;</span><span style="color:#E1E4E8">script src</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"https://fastly.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"</span><span style="color:#E1E4E8">>&#x3C;</span><span style="color:#9ECBFF">/script</span><span style="color:#F97583">></span></span>
<span class="line"><span style="color:#F97583">&#x3C;</span><span style="color:#E1E4E8">script src</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"https://fastly.jsdelivr.net/npm/meting/dist/Meting.min.js"</span><span style="color:#E1E4E8">>&#x3C;</span><span style="color:#9ECBFF">/script</span><span style="color:#F97583">></span></span></code></pre>
<p>新建页面shuoshuo,在文件内写入一下内容:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#B392F0">---</span></span>
<span class="line"><span style="color:#B392F0">title:</span><span style="color:#9ECBFF"> 日常哔哔,键盘侠的日常吐槽</span></span>
<span class="line"><span style="color:#B392F0">aside:</span><span style="color:#79B8FF"> false</span></span>
<span class="line"><span style="color:#B392F0">---</span></span>
<span class="line"><span style="color:#F97583">&#x3C;</span><span style="color:#E1E4E8">div id</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"talk"</span><span style="color:#E1E4E8">>&#x3C;</span><span style="color:#9ECBFF">/div</span><span style="color:#F97583">></span></span>
<span class="line"><span style="color:#F97583">&#x3C;</span><span style="color:#E1E4E8">div class</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"limit"</span><span style="color:#F97583">></span><span style="color:#9ECBFF">-</span><span style="color:#B392F0"> 只展示最近30条说说</span><span style="color:#9ECBFF"> -</span><span style="color:#F97583">&#x3C;</span><span style="color:#9ECBFF">/di</span><span style="color:#E1E4E8">v</span><span style="color:#F97583">></span></span>
<span class="line"><span style="color:#F97583">&#x3C;</span><span style="color:#E1E4E8">script src</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"/js/shuoshuo.js"</span><span style="color:#B392F0"> no-pjax</span><span style="color:#E1E4E8">>&#x3C;/script></span></span></code></pre>
<p>其中的JS文件地址清自行修改,放在主题目录 <code>/script/</code>目录,自行创建,并写入以下内容:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="js"><code><span class="line"><span style="color:#F97583">function</span><span style="color:#B392F0"> renderTalks</span><span style="color:#E1E4E8">() {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> talkContainer</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">querySelector</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'#talk'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> domain</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> 'https://mm.biss.click'</span><span style="color:#E1E4E8">; </span></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (</span><span style="color:#F97583">!</span><span style="color:#E1E4E8">talkContainer) </span><span style="color:#F97583">return</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> talkContainer.innerHTML </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> ''</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#B392F0"> generateIconSVG</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#9ECBFF"> `&#x3C;svg viewBox="0 0 512 512"xmlns="http://www.w3.org/2000/svg"class="is-badge icon">&#x3C;path d="m512 268c0 17.9-4.3 34.5-12.9 49.7s-20.1 27.1-34.6 35.4c.4 2.7.6 6.9.6 12.6 0 27.1-9.1 50.1-27.1 69.1-18.1 19.1-39.9 28.6-65.4 28.6-11.4 0-22.3-2.1-32.6-6.3-8 16.4-19.5 29.6-34.6 39.7-15 10.2-31.5 15.2-49.4 15.2-18.3 0-34.9-4.9-49.7-14.9-14.9-9.9-26.3-23.2-34.3-40-10.3 4.2-21.1 6.3-32.6 6.3-25.5 0-47.4-9.5-65.7-28.6-18.3-19-27.4-42.1-27.4-69.1 0-3 .4-7.2 1.1-12.6-14.5-8.4-26-20.2-34.6-35.4-8.5-15.2-12.8-31.8-12.8-49.7 0-19 4.8-36.5 14.3-52.3s22.3-27.5 38.3-35.1c-4.2-11.4-6.3-22.9-6.3-34.3 0-27 9.1-50.1 27.4-69.1s40.2-28.6 65.7-28.6c11.4 0 22.3 2.1 32.6 6.3 8-16.4 19.5-29.6 34.6-39.7 15-10.1 31.5-15.2 49.4-15.2s34.4 5.1 49.4 15.1c15 10.1 26.6 23.3 34.6 39.7 10.3-4.2 21.1-6.3 32.6-6.3 25.5 0 47.3 9.5 65.4 28.6s27.1 42.1 27.1 69.1c0 12.6-1.9 24-5.7 34.3 16 7.6 28.8 19.3 38.3 35.1 9.5 15.9 14.3 33.4 14.3 52.4zm-266.9 77.1 105.7-158.3c2.7-4.2 3.5-8.8 2.6-13.7-1-4.9-3.5-8.8-7.7-11.4-4.2-2.7-8.8-3.6-13.7-2.9-5 .8-9 3.2-12 7.4l-93.1 140-42.9-42.8c-3.8-3.8-8.2-5.6-13.1-5.4-5 .2-9.3 2-13.1 5.4-3.4 3.4-5.1 7.7-5.1 12.9 0 5.1 1.7 9.4 5.1 12.9l58.9 58.9 2.9 2.3c3.4 2.3 6.9 3.4 10.3 3.4 6.7-.1 11.8-2.9 15.2-8.7z"fill="#1da1f2">&#x3C;/path>&#x3C;/svg>`</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#B392F0"> waterfall</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> function</span><span style="color:#B392F0"> b</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70">b</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#F97583"> var</span><span style="color:#E1E4E8"> c </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> window.</span><span style="color:#B392F0">getComputedStyle</span><span style="color:#E1E4E8">(b);</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#B392F0"> parseFloat</span><span style="color:#E1E4E8">(c[</span><span style="color:#9ECBFF">"margin"</span><span style="color:#F97583"> +</span><span style="color:#E1E4E8"> a]) </span><span style="color:#F97583">||</span><span style="color:#79B8FF"> 0</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> function</span><span style="color:#B392F0"> c</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#E1E4E8"> a </span><span style="color:#F97583">+</span><span style="color:#9ECBFF"> "px"</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> function</span><span style="color:#B392F0"> d</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#B392F0"> parseFloat</span><span style="color:#E1E4E8">(a.style.top)</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> function</span><span style="color:#B392F0"> e</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#B392F0"> parseFloat</span><span style="color:#E1E4E8">(a.style.left)</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> function</span><span style="color:#B392F0"> f</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#E1E4E8"> a.clientWidth</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> function</span><span style="color:#B392F0"> g</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#E1E4E8"> a.clientHeight</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> function</span><span style="color:#B392F0"> h</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#B392F0"> d</span><span style="color:#E1E4E8">(a) </span><span style="color:#F97583">+</span><span style="color:#B392F0"> g</span><span style="color:#E1E4E8">(a) </span><span style="color:#F97583">+</span><span style="color:#B392F0"> b</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Bottom"</span><span style="color:#E1E4E8">, a)</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> function</span><span style="color:#B392F0"> i</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#B392F0"> e</span><span style="color:#E1E4E8">(a) </span><span style="color:#F97583">+</span><span style="color:#B392F0"> f</span><span style="color:#E1E4E8">(a) </span><span style="color:#F97583">+</span><span style="color:#B392F0"> b</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Right"</span><span style="color:#E1E4E8">, a)</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> function</span><span style="color:#B392F0"> j</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#E1E4E8"> a </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> a.</span><span style="color:#B392F0">sort</span><span style="color:#E1E4E8">(</span><span style="color:#F97583">function</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70">b</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#B392F0"> h</span><span style="color:#E1E4E8">(a) </span><span style="color:#F97583">===</span><span style="color:#B392F0"> h</span><span style="color:#E1E4E8">(b) </span><span style="color:#F97583">?</span><span style="color:#B392F0"> e</span><span style="color:#E1E4E8">(b) </span><span style="color:#F97583">-</span><span style="color:#B392F0"> e</span><span style="color:#E1E4E8">(a) </span><span style="color:#F97583">:</span><span style="color:#B392F0"> h</span><span style="color:#E1E4E8">(b) </span><span style="color:#F97583">-</span><span style="color:#B392F0"> h</span><span style="color:#E1E4E8">(a)</span></span>
<span class="line"><span style="color:#E1E4E8"> })</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> function</span><span style="color:#B392F0"> k</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">b</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#B392F0"> f</span><span style="color:#E1E4E8">(a) </span><span style="color:#F97583">!=</span><span style="color:#E1E4E8"> t </span><span style="color:#F97583">&#x26;&#x26;</span><span style="color:#E1E4E8"> (b.target.</span><span style="color:#B392F0">removeEventListener</span><span style="color:#E1E4E8">(b.type, </span><span style="color:#79B8FF">arguments</span><span style="color:#E1E4E8">.callee), </span><span style="color:#B392F0">waterfall</span><span style="color:#E1E4E8">(a))</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#9ECBFF"> "string"</span><span style="color:#F97583"> ==</span><span style="color:#F97583"> typeof</span><span style="color:#E1E4E8"> a </span><span style="color:#F97583">&#x26;&#x26;</span><span style="color:#E1E4E8"> (a </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">querySelector</span><span style="color:#E1E4E8">(a));</span></span>
<span class="line"><span style="color:#F97583"> var</span><span style="color:#E1E4E8"> l </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> [].map.</span><span style="color:#B392F0">call</span><span style="color:#E1E4E8">(a.children, </span><span style="color:#F97583">function</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#E1E4E8"> a.style.position </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> "absolute"</span><span style="color:#E1E4E8">, a</span></span>
<span class="line"><span style="color:#E1E4E8"> });</span></span>
<span class="line"><span style="color:#E1E4E8"> a.style.position </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> "relative"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583"> var</span><span style="color:#E1E4E8"> m </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> [];</span></span>
<span class="line"><span style="color:#E1E4E8"> l.</span><span style="color:#79B8FF">length</span><span style="color:#F97583"> &#x26;&#x26;</span><span style="color:#E1E4E8"> (l[</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">].style.top </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> "0px"</span><span style="color:#E1E4E8">, l[</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">].style.left </span><span style="color:#F97583">=</span><span style="color:#B392F0"> c</span><span style="color:#E1E4E8">(</span><span style="color:#B392F0">b</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Left"</span><span style="color:#E1E4E8">, l[</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">])), m.</span><span style="color:#B392F0">push</span><span style="color:#E1E4E8">(l[</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">]));</span></span>
<span class="line"><span style="color:#F97583"> for</span><span style="color:#E1E4E8"> (</span><span style="color:#F97583">var</span><span style="color:#E1E4E8"> n </span><span style="color:#F97583">=</span><span style="color:#79B8FF"> 1</span><span style="color:#E1E4E8">; n </span><span style="color:#F97583">&#x3C;</span><span style="color:#E1E4E8"> l.</span><span style="color:#79B8FF">length</span><span style="color:#E1E4E8">; n</span><span style="color:#F97583">++</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#F97583"> var</span><span style="color:#E1E4E8"> o </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> l[n </span><span style="color:#F97583">-</span><span style="color:#79B8FF"> 1</span><span style="color:#E1E4E8">],</span></span>
<span class="line"><span style="color:#E1E4E8"> p </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> l[n],</span></span>
<span class="line"><span style="color:#E1E4E8"> q </span><span style="color:#F97583">=</span><span style="color:#B392F0"> i</span><span style="color:#E1E4E8">(o) </span><span style="color:#F97583">+</span><span style="color:#B392F0"> f</span><span style="color:#E1E4E8">(p) </span><span style="color:#F97583">&#x3C;=</span><span style="color:#B392F0"> f</span><span style="color:#E1E4E8">(a);</span></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (</span><span style="color:#F97583">!</span><span style="color:#E1E4E8">q) </span><span style="color:#F97583">break</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> p.style.top </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> o.style.top, p.style.left </span><span style="color:#F97583">=</span><span style="color:#B392F0"> c</span><span style="color:#E1E4E8">(</span><span style="color:#B392F0">i</span><span style="color:#E1E4E8">(o) </span><span style="color:#F97583">+</span><span style="color:#B392F0"> b</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Left"</span><span style="color:#E1E4E8">, p)), m.</span><span style="color:#B392F0">push</span><span style="color:#E1E4E8">(p)</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#F97583"> for</span><span style="color:#E1E4E8"> (; n </span><span style="color:#F97583">&#x3C;</span><span style="color:#E1E4E8"> l.</span><span style="color:#79B8FF">length</span><span style="color:#E1E4E8">; n</span><span style="color:#F97583">++</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#B392F0"> j</span><span style="color:#E1E4E8">(m);</span></span>
<span class="line"><span style="color:#F97583"> var</span><span style="color:#E1E4E8"> p </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> l[n],</span></span>
<span class="line"><span style="color:#E1E4E8"> r </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> m.</span><span style="color:#B392F0">pop</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8"> p.style.top </span><span style="color:#F97583">=</span><span style="color:#B392F0"> c</span><span style="color:#E1E4E8">(</span><span style="color:#B392F0">h</span><span style="color:#E1E4E8">(r) </span><span style="color:#F97583">+</span><span style="color:#B392F0"> b</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Top"</span><span style="color:#E1E4E8">, p)), p.style.left </span><span style="color:#F97583">=</span><span style="color:#B392F0"> c</span><span style="color:#E1E4E8">(</span><span style="color:#B392F0">e</span><span style="color:#E1E4E8">(r)), m.</span><span style="color:#B392F0">push</span><span style="color:#E1E4E8">(p)</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#B392F0"> j</span><span style="color:#E1E4E8">(m);</span></span>
<span class="line"><span style="color:#F97583"> var</span><span style="color:#E1E4E8"> s </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> m[</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">];</span></span>
<span class="line"><span style="color:#E1E4E8"> a.style.height </span><span style="color:#F97583">=</span><span style="color:#B392F0"> c</span><span style="color:#E1E4E8">(</span><span style="color:#B392F0">h</span><span style="color:#E1E4E8">(s) </span><span style="color:#F97583">+</span><span style="color:#B392F0"> b</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Bottom"</span><span style="color:#E1E4E8">, s));</span></span>
<span class="line"><span style="color:#F97583"> var</span><span style="color:#E1E4E8"> t </span><span style="color:#F97583">=</span><span style="color:#B392F0"> f</span><span style="color:#E1E4E8">(a);</span></span>
<span class="line"><span style="color:#E1E4E8"> window.addEventListener </span><span style="color:#F97583">?</span><span style="color:#E1E4E8"> window.</span><span style="color:#B392F0">addEventListener</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"resize"</span><span style="color:#E1E4E8">, k) </span><span style="color:#F97583">:</span><span style="color:#E1E4E8"> document.body.onresize </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> k</span></span>
<span class="line"><span style="color:#E1E4E8"> };</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#B392F0"> fetchAndRenderTalks</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> url</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> 'https://mm.biss.click/api/memo/list'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> cacheKey</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> 'talksCache'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> cacheTimeKey</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> 'talksCacheTime'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> cacheDuration</span><span style="color:#F97583"> =</span><span style="color:#79B8FF"> 30</span><span style="color:#F97583"> *</span><span style="color:#79B8FF"> 60</span><span style="color:#F97583"> *</span><span style="color:#79B8FF"> 1000</span><span style="color:#E1E4E8">; </span><span style="color:#6A737D">// 半个小时 (30 分钟)</span></span>
<span class="line"><span style="color:#E1E4E8"> </span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> cachedData</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> localStorage.</span><span style="color:#B392F0">getItem</span><span style="color:#E1E4E8">(cacheKey);</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> cachedTime</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> localStorage.</span><span style="color:#B392F0">getItem</span><span style="color:#E1E4E8">(cacheTimeKey);</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> currentTime</span><span style="color:#F97583"> =</span><span style="color:#F97583"> new</span><span style="color:#B392F0"> Date</span><span style="color:#E1E4E8">().</span><span style="color:#B392F0">getTime</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8"> </span></span>
<span class="line"><span style="color:#6A737D"> // 判断缓存是否有效</span></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (cachedData </span><span style="color:#F97583">&#x26;&#x26;</span><span style="color:#E1E4E8"> cachedTime </span><span style="color:#F97583">&#x26;&#x26;</span><span style="color:#E1E4E8"> (currentTime </span><span style="color:#F97583">-</span><span style="color:#E1E4E8"> cachedTime </span><span style="color:#F97583">&#x3C;</span><span style="color:#E1E4E8"> cacheDuration)) {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> data</span><span style="color:#F97583"> =</span><span style="color:#79B8FF"> JSON</span><span style="color:#E1E4E8">.</span><span style="color:#B392F0">parse</span><span style="color:#E1E4E8">(cachedData);</span></span>
<span class="line"><span style="color:#B392F0"> renderTalks</span><span style="color:#E1E4E8">(data); </span><span style="color:#6A737D">// 使用缓存渲染数据</span></span>
<span class="line"><span style="color:#E1E4E8"> } </span><span style="color:#F97583">else</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (talkContainer) {</span></span>
<span class="line"><span style="color:#E1E4E8"> talkContainer.innerHTML </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> ''</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0"> fetch</span><span style="color:#E1E4E8">(url, {</span></span>
<span class="line"><span style="color:#E1E4E8"> method: </span><span style="color:#9ECBFF">'POST'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8"> headers: {</span></span>
<span class="line"><span style="color:#9ECBFF"> 'Content-Type'</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'application/json'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8"> },</span></span>
<span class="line"><span style="color:#E1E4E8"> body: </span><span style="color:#79B8FF">JSON</span><span style="color:#E1E4E8">.</span><span style="color:#B392F0">stringify</span><span style="color:#E1E4E8">({</span></span>
<span class="line"><span style="color:#E1E4E8"> size: </span><span style="color:#79B8FF">30</span></span>
<span class="line"><span style="color:#E1E4E8"> })</span></span>
<span class="line"><span style="color:#E1E4E8"> })</span></span>
<span class="line"><span style="color:#E1E4E8"> .</span><span style="color:#B392F0">then</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">res</span><span style="color:#F97583"> =></span><span style="color:#E1E4E8"> res.</span><span style="color:#B392F0">json</span><span style="color:#E1E4E8">())</span></span>
<span class="line"><span style="color:#E1E4E8"> .</span><span style="color:#B392F0">then</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">data</span><span style="color:#F97583"> =></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (data.code </span><span style="color:#F97583">===</span><span style="color:#79B8FF"> 0</span><span style="color:#F97583"> &#x26;&#x26;</span><span style="color:#E1E4E8"> data.data </span><span style="color:#F97583">&#x26;&#x26;</span><span style="color:#E1E4E8"> Array.</span><span style="color:#B392F0">isArray</span><span style="color:#E1E4E8">(data.data.list)) {</span></span>
<span class="line"><span style="color:#6A737D"> // 缓存数据</span></span>
<span class="line"><span style="color:#E1E4E8"> localStorage.</span><span style="color:#B392F0">setItem</span><span style="color:#E1E4E8">(cacheKey, </span><span style="color:#79B8FF">JSON</span><span style="color:#E1E4E8">.</span><span style="color:#B392F0">stringify</span><span style="color:#E1E4E8">(data.data.list));</span></span>
<span class="line"><span style="color:#E1E4E8"> localStorage.</span><span style="color:#B392F0">setItem</span><span style="color:#E1E4E8">(cacheTimeKey, currentTime.</span><span style="color:#B392F0">toString</span><span style="color:#E1E4E8">());</span></span>
<span class="line"><span style="color:#B392F0"> renderTalks</span><span style="color:#E1E4E8">(data.data.list); </span><span style="color:#6A737D">// 渲染数据</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8"> })</span></span>
<span class="line"><span style="color:#E1E4E8"> .</span><span style="color:#B392F0">catch</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">error</span><span style="color:#F97583"> =></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8"> console.</span><span style="color:#B392F0">error</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'Error fetching data:'</span><span style="color:#E1E4E8">, error);</span></span>
<span class="line"><span style="color:#E1E4E8"> });</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8"> </span></span>
<span class="line"><span style="color:#6A737D"> // 渲染函数</span></span>
<span class="line"><span style="color:#F97583"> function</span><span style="color:#B392F0"> renderTalks</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">list</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#6A737D"> // 确保 data 是一个数组</span></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (Array.</span><span style="color:#B392F0">isArray</span><span style="color:#E1E4E8">(list)) {</span></span>
<span class="line"><span style="color:#F97583"> let</span><span style="color:#E1E4E8"> items </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> list.</span><span style="color:#B392F0">map</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">item</span><span style="color:#F97583"> =></span><span style="color:#B392F0"> formatTalk</span><span style="color:#E1E4E8">(item, url));</span></span>
<span class="line"><span style="color:#E1E4E8"> items.</span><span style="color:#B392F0">forEach</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">item</span><span style="color:#F97583"> =></span><span style="color:#E1E4E8"> talkContainer.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(</span><span style="color:#B392F0">generateTalkElement</span><span style="color:#E1E4E8">(item)));</span></span>
<span class="line"><span style="color:#B392F0"> waterfall</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'#talk'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> } </span><span style="color:#F97583">else</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8"> console.</span><span style="color:#B392F0">error</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'Data is not an array:'</span><span style="color:#E1E4E8">, list);</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8"> };</span></span>
<span class="line"><span style="color:#E1E4E8"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#B392F0"> formatTalk</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">item</span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70">url</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> let</span><span style="color:#E1E4E8"> date </span><span style="color:#F97583">=</span><span style="color:#B392F0"> formatTime</span><span style="color:#E1E4E8">(</span><span style="color:#F97583">new</span><span style="color:#B392F0"> Date</span><span style="color:#E1E4E8">(item.createdAt).</span><span style="color:#B392F0">toString</span><span style="color:#E1E4E8">());</span></span>
<span class="line"><span style="color:#F97583"> let</span><span style="color:#E1E4E8"> content </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> item.content;</span></span>
<span class="line"><span style="color:#F97583"> let</span><span style="color:#E1E4E8"> imgs </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> item.imgs </span><span style="color:#F97583">?</span><span style="color:#E1E4E8"> item.imgs.</span><span style="color:#B392F0">split</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">','</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">:</span><span style="color:#E1E4E8"> [];</span></span>
<span class="line"><span style="color:#F97583"> let</span><span style="color:#E1E4E8"> text </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> content;</span></span>
<span class="line"><span style="color:#E1E4E8"> content </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> text.</span><span style="color:#B392F0">replace</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">/</span><span style="color:#85E89D;font-weight:bold">\[</span><span style="color:#DBEDFF">(</span><span style="color:#79B8FF">.</span><span style="color:#F97583">*?</span><span style="color:#DBEDFF">)</span><span style="color:#85E89D;font-weight:bold">\]\(</span><span style="color:#DBEDFF">(</span><span style="color:#79B8FF">.</span><span style="color:#F97583">*?</span><span style="color:#DBEDFF">)</span><span style="color:#85E89D;font-weight:bold">\)</span><span style="color:#9ECBFF">/</span><span style="color:#F97583">g</span><span style="color:#E1E4E8">, </span><span style="color:#9ECBFF">`&#x3C;a href="$2">@$1&#x3C;/a>`</span><span style="color:#E1E4E8">)</span></span>
<span class="line"><span style="color:#E1E4E8"> .</span><span style="color:#B392F0">replace</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">/</span><span style="color:#DBEDFF">- </span><span style="color:#85E89D;font-weight:bold">\[</span><span style="color:#85E89D;font-weight:bold"> \]</span><span style="color:#9ECBFF">/</span><span style="color:#F97583">g</span><span style="color:#E1E4E8">, </span><span style="color:#9ECBFF">'⚪'</span><span style="color:#E1E4E8">)</span></span>
<span class="line"><span style="color:#E1E4E8"> .</span><span style="color:#B392F0">replace</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">/</span><span style="color:#DBEDFF">- </span><span style="color:#85E89D;font-weight:bold">\[</span><span style="color:#DBEDFF">x</span><span style="color:#85E89D;font-weight:bold">\]</span><span style="color:#9ECBFF">/</span><span style="color:#F97583">g</span><span style="color:#E1E4E8">, </span><span style="color:#9ECBFF">'⚫'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#6A737D"> // 保留换行符,转换 \n 为 &#x3C;br></span></span>
<span class="line"><span style="color:#E1E4E8"> content </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> content.</span><span style="color:#B392F0">replace</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">/</span><span style="color:#79B8FF">\n</span><span style="color:#9ECBFF">/</span><span style="color:#F97583">g</span><span style="color:#E1E4E8">, </span><span style="color:#9ECBFF">'&#x3C;br>'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#6A737D"> // 将content用一个类包裹,便于后续处理</span></span>
<span class="line"><span style="color:#E1E4E8"> content </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> `&#x3C;div class="talk_content_text">${</span><span style="color:#E1E4E8">content</span><span style="color:#9ECBFF">}&#x3C;/div>`</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (imgs.</span><span style="color:#79B8FF">length</span><span style="color:#F97583"> ></span><span style="color:#79B8FF"> 0</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> imgDiv</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'div'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> imgDiv.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'zone_imgbox'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> imgs.</span><span style="color:#B392F0">forEach</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">e</span><span style="color:#F97583"> =></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> imgLink</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'a'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> imgUrl</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> domain </span><span style="color:#F97583">+</span><span style="color:#E1E4E8"> e;</span></span>
<span class="line"><span style="color:#E1E4E8"> imgLink.href </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> imgUrl;</span></span>
<span class="line"><span style="color:#E1E4E8"> imgLink.</span><span style="color:#B392F0">setAttribute</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'data-fancybox'</span><span style="color:#E1E4E8">, </span><span style="color:#9ECBFF">'gallery'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> imgLink.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'fancybox'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> imgLink.</span><span style="color:#B392F0">setAttribute</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'data-thumb'</span><span style="color:#E1E4E8">, e);</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> imgTag</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'img'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> imgTag.src </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> domain </span><span style="color:#F97583">+</span><span style="color:#E1E4E8"> e;</span></span>
<span class="line"><span style="color:#E1E4E8"> imgLink.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(imgTag);</span></span>
<span class="line"><span style="color:#E1E4E8"> imgDiv.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(imgLink);</span></span>
<span class="line"><span style="color:#E1E4E8"> });</span></span>
<span class="line"><span style="color:#E1E4E8"> content </span><span style="color:#F97583">+=</span><span style="color:#E1E4E8"> imgDiv.outerHTML;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D"> // 外链分享功能</span></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (item.externalUrl) {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> externalUrl</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> item.externalUrl;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> externalTitle</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> item.externalTitle;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> externalFavicon</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> item.externalFavicon;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> externalContainer</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> `</span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="shuoshuo-external-link"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;a class="external-link" href="${</span><span style="color:#E1E4E8">externalUrl</span><span style="color:#9ECBFF">}" target="_blank" rel="external nofollow noopener noreferrer"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="external-link-left" style="background-image: url(${</span><span style="color:#E1E4E8">externalFavicon</span><span style="color:#9ECBFF">})">&#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="external-link-right"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="external-link-title">${</span><span style="color:#E1E4E8">externalTitle</span><span style="color:#9ECBFF">}&#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div>点击跳转&#x3C;i class="fa-solid fa-angle-right">&#x3C;/i>&#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/a></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/div>`</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8"> content </span><span style="color:#F97583">+=</span><span style="color:#E1E4E8"> externalContainer;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> ext</span><span style="color:#F97583"> =</span><span style="color:#79B8FF"> JSON</span><span style="color:#E1E4E8">.</span><span style="color:#B392F0">parse</span><span style="color:#E1E4E8">(item.ext </span><span style="color:#F97583">||</span><span style="color:#9ECBFF"> '{}'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (ext.music </span><span style="color:#F97583">&#x26;&#x26;</span><span style="color:#E1E4E8"> ext.music.id) {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> music</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> ext.music;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> musicUrl</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> music.api.</span><span style="color:#B392F0">replace</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">':server'</span><span style="color:#E1E4E8">, music.server)</span></span>
<span class="line"><span style="color:#E1E4E8"> .</span><span style="color:#B392F0">replace</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">':type'</span><span style="color:#E1E4E8">, music.type)</span></span>
<span class="line"><span style="color:#E1E4E8"> .</span><span style="color:#B392F0">replace</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">':id'</span><span style="color:#E1E4E8">, music.id);</span></span>
<span class="line"><span style="color:#E1E4E8"> content </span><span style="color:#F97583">+=</span><span style="color:#9ECBFF"> `</span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;meting-js server="${</span><span style="color:#E1E4E8">music</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">server</span><span style="color:#9ECBFF">}" type="${</span><span style="color:#E1E4E8">music</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">type</span><span style="color:#9ECBFF">}" id="${</span><span style="color:#E1E4E8">music</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">id</span><span style="color:#9ECBFF">}" api="${</span><span style="color:#E1E4E8">music</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">api</span><span style="color:#9ECBFF">}">&#x3C;/meting-js></span></span>
<span class="line"><span style="color:#9ECBFF"> `</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (ext.doubanMovie </span><span style="color:#F97583">&#x26;&#x26;</span><span style="color:#E1E4E8"> ext.doubanMovie.id) {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> doubanMovie</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> ext.doubanMovie;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> doubanMovieUrl</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> doubanMovie.url;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> doubanTitle</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> doubanMovie.title;</span></span>
<span class="line"><span style="color:#6A737D"> // const doubanDesc = doubanMovie.desc || '暂无描述';</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> doubanImage</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> doubanMovie.image;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> doubanDirector</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> doubanMovie.director </span><span style="color:#F97583">||</span><span style="color:#9ECBFF"> '未知导演'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> doubanRating</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> doubanMovie.rating </span><span style="color:#F97583">||</span><span style="color:#9ECBFF"> '暂无评分'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#6A737D"> // const doubanReleaseDate = doubanMovie.releaseDate || '未知上映时间';</span></span>
<span class="line"><span style="color:#6A737D"> // const doubanActors = doubanMovie.actors || '未知演员';</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> doubanRuntime</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> doubanMovie.runtime </span><span style="color:#F97583">||</span><span style="color:#9ECBFF"> '未知时长'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8"> content </span><span style="color:#F97583">+=</span><span style="color:#9ECBFF"> `</span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;a class="douban-card" href="${</span><span style="color:#E1E4E8">doubanMovieUrl</span><span style="color:#9ECBFF">}" target="_blank"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-bgimg" style="background-image: url('${</span><span style="color:#E1E4E8">doubanImage</span><span style="color:#9ECBFF">}');">&#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-left"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-img" style="background-image: url('${</span><span style="color:#E1E4E8">doubanImage</span><span style="color:#9ECBFF">}');">&#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-right"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-item">&#x3C;span>电影名: &#x3C;/span>&#x3C;strong>${</span><span style="color:#E1E4E8">doubanTitle</span><span style="color:#9ECBFF">}&#x3C;/strong>&#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-item">&#x3C;span>导演: &#x3C;/span>&#x3C;span>${</span><span style="color:#E1E4E8">doubanDirector</span><span style="color:#9ECBFF">}&#x3C;/span>&#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-item">&#x3C;span>评分: &#x3C;/span>&#x3C;span>${</span><span style="color:#E1E4E8">doubanRating</span><span style="color:#9ECBFF">}&#x3C;/span>&#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-item">&#x3C;span>时长: &#x3C;/span>&#x3C;span>${</span><span style="color:#E1E4E8">doubanRuntime</span><span style="color:#9ECBFF">}&#x3C;/span>&#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/a></span></span>
<span class="line"><span style="color:#9ECBFF"> `</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (ext.doubanBook </span><span style="color:#F97583">&#x26;&#x26;</span><span style="color:#E1E4E8"> ext.doubanBook.id) {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> doubanBook</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> ext.doubanBook;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> bookUrl</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> doubanBook.url;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> bookTitle</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> doubanBook.title;</span></span>
<span class="line"><span style="color:#6A737D"> // const bookDesc = doubanBook.desc;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> bookImage</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> doubanBook.image;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> bookAuthor</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> doubanBook.author;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> bookRating</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> doubanBook.rating;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> bookPubDate</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> doubanBook.pubDate;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> bookTemplate</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> `</span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;a class="douban-card" href="${</span><span style="color:#E1E4E8">bookUrl</span><span style="color:#9ECBFF">}" target="_blank"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-bgimg" style="background-image: url('${</span><span style="color:#E1E4E8">bookImage</span><span style="color:#9ECBFF">}');">&#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-left"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-img" style="background-image: url('${</span><span style="color:#E1E4E8">bookImage</span><span style="color:#9ECBFF">}');">&#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-right"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-item"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;span>书名: &#x3C;/span>&#x3C;strong>${</span><span style="color:#E1E4E8">bookTitle</span><span style="color:#9ECBFF">}&#x3C;/strong></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-item"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;span>作者: &#x3C;/span>&#x3C;span>${</span><span style="color:#E1E4E8">bookAuthor</span><span style="color:#9ECBFF">}&#x3C;/span></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-item"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;span>出版年份: &#x3C;/span>&#x3C;span>${</span><span style="color:#E1E4E8">bookPubDate</span><span style="color:#9ECBFF">}&#x3C;/span></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div class="douban-card-item"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;span>评分: &#x3C;/span>&#x3C;span>${</span><span style="color:#E1E4E8">bookRating</span><span style="color:#9ECBFF">}&#x3C;/span></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/a></span></span>
<span class="line"><span style="color:#9ECBFF"> `</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8"> content </span><span style="color:#F97583">+=</span><span style="color:#E1E4E8"> bookTemplate;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (ext.video </span><span style="color:#F97583">&#x26;&#x26;</span><span style="color:#E1E4E8"> ext.video.type) {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> videoType</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> ext.video.type;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> videoUrl</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> ext.video.value;</span></span>
<span class="line"><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (videoType </span><span style="color:#F97583">===</span><span style="color:#9ECBFF"> 'bilibili'</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#6A737D"> // Bilibili 视频模板</span></span>
<span class="line"><span style="color:#6A737D"> // 从形如https://www.bilibili.com/video/BV1VGAPeAEMQ/?vd_source=91b3158d27d98ff41f842508c3794a13 的链接中提取视频 BV1VGAPeAEMQ</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> biliTemplate</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> `</span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div style="position: relative; padding: 30% 45%; margin-top: 10px;"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;iframe </span></span>
<span class="line"><span style="color:#9ECBFF"> style="position: absolute; width: 100%; height: 100%; left: 0; top: 0; border-radius: 12px;" </span></span>
<span class="line"><span style="color:#9ECBFF"> src="${</span><span style="color:#E1E4E8">videoUrl</span><span style="color:#9ECBFF">}&#x26;autoplay=0"</span></span>
<span class="line"><span style="color:#9ECBFF"> scrolling="no" </span></span>
<span class="line"><span style="color:#9ECBFF"> frameborder="no" </span></span>
<span class="line"><span style="color:#9ECBFF"> allowfullscreen></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/iframe></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> `</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#6A737D"> // 将模板插入到 DOM 中</span></span>
<span class="line"><span style="color:#E1E4E8"> content </span><span style="color:#F97583">+=</span><span style="color:#E1E4E8"> biliTemplate;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8"> } </span><span style="color:#F97583">else</span><span style="color:#F97583"> if</span><span style="color:#E1E4E8"> (videoType </span><span style="color:#F97583">===</span><span style="color:#9ECBFF"> 'youtube'</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#6A737D"> // YouTube 视频模板</span></span>
<span class="line"><span style="color:#6A737D"> // 从形如https://youtu.be/2V6lvCUPT8I?si=DVhUas6l6qlAr6Ru的链接中提取视频 ID2V6lvCUPT8I</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> youtubeTemplate</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> `</span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;div style="position: relative; padding: 30% 45%; margin-top: 10px;"></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;iframe width="100%"</span></span>
<span class="line"><span style="color:#9ECBFF"> style="position: absolute; width: 100%; height: 100%; left: 0; top: 0; border-radius: 12px;"</span></span>
<span class="line"><span style="color:#9ECBFF"> src="${</span><span style="color:#E1E4E8">videoUrl</span><span style="color:#9ECBFF">}"</span></span>
<span class="line"><span style="color:#9ECBFF"> title="YouTube video player" </span></span>
<span class="line"><span style="color:#9ECBFF"> frameborder="0" </span></span>
<span class="line"><span style="color:#9ECBFF"> allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" </span></span>
<span class="line"><span style="color:#9ECBFF"> referrerpolicy="strict-origin-when-cross-origin" </span></span>
<span class="line"><span style="color:#9ECBFF"> allowfullscreen></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/iframe></span></span>
<span class="line"><span style="color:#9ECBFF"> &#x3C;/div></span></span>
<span class="line"><span style="color:#9ECBFF"> `</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#6A737D"> // 将模板插入到 DOM 中</span></span>
<span class="line"><span style="color:#E1E4E8"> content </span><span style="color:#F97583">+=</span><span style="color:#E1E4E8"> youtubeTemplate;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8"> content: content,</span></span>
<span class="line"><span style="color:#E1E4E8"> user: item.user.nickname </span><span style="color:#F97583">||</span><span style="color:#9ECBFF"> '匿名'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8"> avatar: item.user.avatarUrl </span><span style="color:#F97583">||</span><span style="color:#9ECBFF"> 'https://p.liiiu.cn/i/2024/03/29/66061417537af.png'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8"> date: date,</span></span>
<span class="line"><span style="color:#E1E4E8"> location: item.location </span><span style="color:#F97583">||</span><span style="color:#9ECBFF"> '山西'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8"> tags: item.tags </span><span style="color:#F97583">?</span><span style="color:#E1E4E8"> item.tags.</span><span style="color:#B392F0">split</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">','</span><span style="color:#E1E4E8">).</span><span style="color:#B392F0">filter</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">tag</span><span style="color:#F97583"> =></span><span style="color:#E1E4E8"> tag.</span><span style="color:#B392F0">trim</span><span style="color:#E1E4E8">() </span><span style="color:#F97583">!==</span><span style="color:#9ECBFF"> ''</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">:</span><span style="color:#E1E4E8"> [</span><span style="color:#9ECBFF">'无标签'</span><span style="color:#E1E4E8">],</span></span>
<span class="line"><span style="color:#E1E4E8"> text: content.</span><span style="color:#B392F0">replace</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">/</span><span style="color:#85E89D;font-weight:bold">\[</span><span style="color:#DBEDFF">(</span><span style="color:#79B8FF">.</span><span style="color:#F97583">*?</span><span style="color:#DBEDFF">)</span><span style="color:#85E89D;font-weight:bold">\]\(</span><span style="color:#DBEDFF">(</span><span style="color:#79B8FF">.</span><span style="color:#F97583">*?</span><span style="color:#DBEDFF">)</span><span style="color:#85E89D;font-weight:bold">\)</span><span style="color:#9ECBFF">/</span><span style="color:#F97583">g</span><span style="color:#E1E4E8">, </span><span style="color:#9ECBFF">'[链接]'</span><span style="color:#F97583"> +</span><span style="color:#9ECBFF"> `${</span><span style="color:#E1E4E8">imgs</span><span style="color:#9ECBFF">.</span><span style="color:#79B8FF">length</span><span style="color:#F97583"> ?</span><span style="color:#9ECBFF"> '[图片]'</span><span style="color:#F97583"> :</span><span style="color:#9ECBFF"> ''}`</span><span style="color:#E1E4E8">)</span></span>
<span class="line"><span style="color:#E1E4E8"> };</span></span>
<span class="line"><span style="color:#E1E4E8"> };</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#B392F0"> generateTalkElement</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">item</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> talkItem</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'div'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkItem.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'talk_item'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> talkMeta</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'div'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkMeta.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'talk_meta'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> avatar</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'img'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> avatar.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'no-lightbox avatar'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> avatar.src </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> item.avatar;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> info</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'div'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> info.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'info'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> talkNick</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'span'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkNick.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'talk_nick'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> talkNick.innerHTML </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> `${</span><span style="color:#E1E4E8">item</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">user</span><span style="color:#9ECBFF">} ${</span><span style="color:#B392F0">generateIconSVG</span><span style="color:#9ECBFF">()</span><span style="color:#9ECBFF">}`</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> talkDate</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'span'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkDate.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'talk_date'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> talkDate.textContent </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> item.date;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> talkContent</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'div'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkContent.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'talk_content'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> talkContent.innerHTML </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> item.content;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> talkBottom</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'div'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkBottom.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'talk_bottom'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> TagContainer</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'div'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> talkTag</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'span'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkTag.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'talk_tag'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> talkTag.textContent </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> `🏷️${</span><span style="color:#E1E4E8">item</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">tags</span><span style="color:#9ECBFF">}`</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> locationTag</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'span'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> locationTag.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'location_tag'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> locationTag.textContent </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> `🌍${</span><span style="color:#E1E4E8">item</span><span style="color:#9ECBFF">.</span><span style="color:#E1E4E8">location</span><span style="color:#9ECBFF">}`</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8"> TagContainer.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(talkTag);</span></span>
<span class="line"><span style="color:#E1E4E8"> TagContainer.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(locationTag);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> commentLink</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'a'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> commentLink.href </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'javascript:;'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> commentLink.</span><span style="color:#B392F0">onclick</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#B392F0"> goComment</span><span style="color:#E1E4E8">(item.text);</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> commentIcon</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'span'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> commentIcon.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'icon'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> commentIconInner</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">createElement</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'i'</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> commentIconInner.className </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> 'fa-solid fa-message fa-fw'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> commentIcon.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(commentIconInner);</span></span>
<span class="line"><span style="color:#E1E4E8"> commentLink.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(commentIcon);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8"> talkMeta.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(avatar);</span></span>
<span class="line"><span style="color:#E1E4E8"> info.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(talkNick);</span></span>
<span class="line"><span style="color:#E1E4E8"> info.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(talkDate);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkMeta.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(info);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkItem.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(talkMeta);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkItem.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(talkContent);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkBottom.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(TagContainer);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkBottom.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(commentLink);</span></span>
<span class="line"><span style="color:#E1E4E8"> talkItem.</span><span style="color:#B392F0">appendChild</span><span style="color:#E1E4E8">(talkBottom);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#E1E4E8"> talkItem;</span></span>
<span class="line"><span style="color:#E1E4E8"> };</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#B392F0"> goComment</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">e</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> match</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> e.</span><span style="color:#B392F0">match</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">/</span><span style="color:#DBEDFF">&#x3C;div class="talk_content_text">(</span><span style="color:#79B8FF">[\s\S]</span><span style="color:#F97583">*?</span><span style="color:#DBEDFF">)&#x3C;</span><span style="color:#85E89D;font-weight:bold">\/</span><span style="color:#DBEDFF">div></span><span style="color:#9ECBFF">/</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> textContent</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> match </span><span style="color:#F97583">?</span><span style="color:#E1E4E8"> match[</span><span style="color:#79B8FF">1</span><span style="color:#E1E4E8">] </span><span style="color:#F97583">:</span><span style="color:#9ECBFF"> ""</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> n</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> document.</span><span style="color:#B392F0">querySelector</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">".atk-textarea"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> n.value </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> `> ${</span><span style="color:#E1E4E8">textContent</span><span style="color:#9ECBFF">}</span><span style="color:#79B8FF">\n\n</span><span style="color:#9ECBFF">`</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> n.</span><span style="color:#B392F0">focus</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8"> btf.</span><span style="color:#B392F0">snackbarShow</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"已为您引用该说说,不删除空格效果更佳"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#6A737D"> // const n = document.querySelector(".atk-textarea");</span></span>
<span class="line"><span style="color:#6A737D"> // n.value = `> ${e}\n\n`;</span></span>
<span class="line"><span style="color:#6A737D"> // n.focus();</span></span>
<span class="line"><span style="color:#6A737D"> // btf.snackbarShow("已为您引用该说说,不删除空格效果更佳");</span></span>
<span class="line"><span style="color:#E1E4E8"> };</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#B392F0"> formatTime</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">time</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> d</span><span style="color:#F97583"> =</span><span style="color:#F97583"> new</span><span style="color:#B392F0"> Date</span><span style="color:#E1E4E8">(time);</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> ls</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> [</span></span>
<span class="line"><span style="color:#E1E4E8"> d.</span><span style="color:#B392F0">getFullYear</span><span style="color:#E1E4E8">(),</span></span>
<span class="line"><span style="color:#E1E4E8"> d.</span><span style="color:#B392F0">getMonth</span><span style="color:#E1E4E8">() </span><span style="color:#F97583">+</span><span style="color:#79B8FF"> 1</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8"> d.</span><span style="color:#B392F0">getDate</span><span style="color:#E1E4E8">(),</span></span>
<span class="line"><span style="color:#E1E4E8"> d.</span><span style="color:#B392F0">getHours</span><span style="color:#E1E4E8">(),</span></span>
<span class="line"><span style="color:#E1E4E8"> d.</span><span style="color:#B392F0">getMinutes</span><span style="color:#E1E4E8">(),</span></span>
<span class="line"><span style="color:#E1E4E8"> d.</span><span style="color:#B392F0">getSeconds</span><span style="color:#E1E4E8">(),</span></span>
<span class="line"><span style="color:#E1E4E8"> ];</span></span>
<span class="line"><span style="color:#F97583"> const</span><span style="color:#79B8FF"> r</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> ls.</span><span style="color:#B392F0">map</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">a</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> (a.</span><span style="color:#B392F0">toString</span><span style="color:#E1E4E8">().</span><span style="color:#79B8FF">length</span><span style="color:#F97583"> ===</span><span style="color:#79B8FF"> 1</span><span style="color:#F97583"> ?</span><span style="color:#9ECBFF"> '0'</span><span style="color:#F97583"> +</span><span style="color:#E1E4E8"> a </span><span style="color:#F97583">:</span><span style="color:#E1E4E8"> a));</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#9ECBFF"> `${</span><span style="color:#E1E4E8">r</span><span style="color:#9ECBFF">[</span><span style="color:#79B8FF">0</span><span style="color:#9ECBFF">]</span><span style="color:#9ECBFF">}-${</span><span style="color:#E1E4E8">r</span><span style="color:#9ECBFF">[</span><span style="color:#79B8FF">1</span><span style="color:#9ECBFF">]</span><span style="color:#9ECBFF">}-${</span><span style="color:#E1E4E8">r</span><span style="color:#9ECBFF">[</span><span style="color:#79B8FF">2</span><span style="color:#9ECBFF">]</span><span style="color:#9ECBFF">} ${</span><span style="color:#E1E4E8">r</span><span style="color:#9ECBFF">[</span><span style="color:#79B8FF">3</span><span style="color:#9ECBFF">]</span><span style="color:#9ECBFF">}:${</span><span style="color:#E1E4E8">r</span><span style="color:#9ECBFF">[</span><span style="color:#79B8FF">4</span><span style="color:#9ECBFF">]</span><span style="color:#9ECBFF">}`</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> };</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0"> fetchAndRenderTalks</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">renderTalks</span><span style="color:#E1E4E8">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">// function whenDOMReady() {</span></span>
<span class="line"><span style="color:#6A737D">// const talkContainer = document.querySelector('#talk');</span></span>
<span class="line"><span style="color:#6A737D">// talkContainer.innerHTML = '';</span></span>
<span class="line"><span style="color:#6A737D">// fetchAndRenderTalks();</span></span>
<span class="line"><span style="color:#6A737D">// }</span></span>
<span class="line"><span style="color:#6A737D">// whenDOMReady();</span></span>
<span class="line"><span style="color:#6A737D">// document.addEventListener("pjax:complete", whenDOMReady);</span></span></code></pre>
<p>自行修改js文件中的Moments地址为你的地址,在文件中,有一个gocomment函数,实现的是获取卡片中的文本内容,如果如果出现不匹配的情况,请自行修改一下类名,这里我匹配的是artalk的输入框。在这里我把代码做了修改,因为我不想使用s3,结果导致说说图片无法加载。。。
修改历程:日后再写</p>
<p>然后引入样式文件,这个文件可以在配置文件中引用,也可以在页面文件中类似于shuoshuo.js一样引用,样式内容如下:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="css"><code><span class="line"><span style="color:#B392F0">:root</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-card-bg</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#fff</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-card-border</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">1</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> solid</span><span style="color:#79B8FF"> #e3e8f7</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70"> --card-box-shadow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">0</span><span style="color:#79B8FF"> 3</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 8</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 6</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> rgba</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">7</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">17</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">27</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">0.09</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#FFAB70"> --card-hover-box-shadow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">0</span><span style="color:#79B8FF"> 3</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 8</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 6</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> rgba</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">7</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">17</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">27</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">0.2</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-card-secondbg</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#f1f3f8</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-button-hover-bg</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#2679cc</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-text</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#4c4948</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-button-bg</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#f1f3f8</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-fancybox-bg</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">rgba</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">255</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">255</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">255</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">0.5</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">:root</span><span style="color:#E1E4E8">, [</span><span style="color:#B392F0">data-theme</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">dark</span><span style="color:#E1E4E8">] {</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-card-bg</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#181818</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-card-secondbg</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#30343f</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-card-border</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">1</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> solid</span><span style="color:#79B8FF"> #42444a</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70"> --card-box-shadow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">0</span><span style="color:#79B8FF"> 3</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 8</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 6</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> rgba</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">7</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">17</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">27</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">0.09</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#FFAB70"> --card-hover-box-shadow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">0</span><span style="color:#79B8FF"> 3</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 8</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 6</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> rgba</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">7</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">17</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">27</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">0.2</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-button-bg</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#30343f</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-button-hover-bg</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#2679cc</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-text</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">rgba</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">255</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">255</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">255</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">0.702</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#FFAB70"> --liushen-fancybox-bg</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">rgba</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">,</span><span style="color:#79B8FF">0.5</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">/* 卡片初始化 */</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">calc</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">33.333</span><span style="color:#F97583">%</span><span style="color:#F97583"> -</span><span style="color:#79B8FF"> 6</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> background</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">var</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">--liushen-card-bg</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> border</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">var</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">--liushen-card-border</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> box-shadow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">var</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">--card-box-shadow</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> transition</span><span style="color:#E1E4E8">: box-shadow </span><span style="color:#79B8FF">.3</span><span style="color:#F97583">s</span><span style="color:#79B8FF"> ease-in-out</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> border-radius</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> display</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">flex</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> flex-direction</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">column</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> padding</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">20</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> margin-bottom</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">9</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> margin-right</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">9</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item:hover</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> box-shadow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">var</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">--card-hover-box-shadow</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">@media</span><span style="color:#E1E4E8"> (</span><span style="color:#79B8FF">max-width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">900</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#B392F0"> #talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">calc</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">50</span><span style="color:#F97583">%</span><span style="color:#F97583"> -</span><span style="color:#79B8FF"> 5</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#F97583">@media</span><span style="color:#E1E4E8"> (</span><span style="color:#79B8FF">max-width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">450</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#B392F0"> #talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">calc</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#E1E4E8">{</span></span>
<span class="line"><span style="color:#79B8FF"> position</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">relative</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> box-sizing</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">border-box</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_meta</span><span style="color:#B392F0"> .avatar</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> margin</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">0</span><span style="color:#F97583"> !important</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">60</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> height</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">60</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> border-radius</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_bottom</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_meta</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> display</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">flex</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> align-items</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">center</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_meta</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> display</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">flex</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> align-items</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">center</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> padding-bottom</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">10</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> border-bottom</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">1</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> dashed</span><span style="color:#79B8FF"> grey</span><span style="color:#E1E4E8">; </span><span style="color:#6A737D">/* 添加灰色虚线边框 */</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_bottom</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> margin-top</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">15</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> padding-top</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">10</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> border-top</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">1</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> dashed</span><span style="color:#79B8FF"> grey</span><span style="color:#E1E4E8">; </span><span style="color:#6A737D">/* 添加灰色虚线边框 */</span></span>
<span class="line"><span style="color:#79B8FF"> justify-content</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">space-between</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_meta</span><span style="color:#B392F0"> .info</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> display</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">flex</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> flex-direction</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">column</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> margin-left</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">10</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_meta</span><span style="color:#B392F0"> .info</span><span style="color:#B392F0"> .talk_nick</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#6dbdc3</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> font-size</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">1.2</span><span style="color:#F97583">rem</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_meta</span><span style="color:#B392F0"> .info</span><span style="color:#85E89D"> svg</span><span style="color:#B392F0">.is-badge.icon</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">15</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> padding-top</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">3</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_meta</span><span style="color:#B392F0"> .info</span><span style="color:#85E89D"> span</span><span style="color:#B392F0">.talk_date</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> opacity</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">.6</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_content</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> margin-top</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">10</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_content</span><span style="color:#B392F0"> .zone_imgbox</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> display</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">flex</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> flex-wrap</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">wrap</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70"> --w</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">calc</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">25</span><span style="color:#F97583">%</span><span style="color:#F97583"> -</span><span style="color:#79B8FF"> 8</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> gap</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">10</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> margin-top</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">10</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_content</span><span style="color:#B392F0"> .zone_imgbox</span><span style="color:#85E89D"> a</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> display</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">block</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> border-radius</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">var</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">--w</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> aspect-ratio</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">1</span><span style="color:#E1E4E8">/</span><span style="color:#79B8FF">1</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> position</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">relative</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_content</span><span style="color:#B392F0"> .zone_imgbox</span><span style="color:#85E89D"> a</span><span style="color:#B392F0">:first-child</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> aspect-ratio</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">1.8</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_content</span><span style="color:#B392F0"> .zone_imgbox</span><span style="color:#85E89D"> img</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> border-radius</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">10</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> height</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> margin</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">0</span><span style="color:#F97583"> !important</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> object-fit</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">cover</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#6A737D">/* 底部 */</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_bottom</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> opacity</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">.9</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_bottom</span><span style="color:#B392F0"> .icon</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> float</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">right</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> transition</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">all</span><span style="color:#79B8FF"> .3</span><span style="color:#F97583">s</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_bottom</span><span style="color:#B392F0"> .icon:hover</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#49b1f5</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_bottom</span><span style="color:#85E89D"> span</span><span style="color:#B392F0">.talk_tag</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_bottom</span><span style="color:#85E89D"> span</span><span style="color:#B392F0">.location_tag</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> font-size</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">14</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> background-color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">var</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">--liushen-card-secondbg</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> border-radius</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> padding</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">3</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 15</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 3</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 10</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> transition</span><span style="color:#E1E4E8">: box-shadow </span><span style="color:#79B8FF">0.3</span><span style="color:#F97583">s</span><span style="color:#79B8FF"> ease</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> box-shadow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">0</span><span style="color:#79B8FF"> 2</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 4</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> rgba</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">0.1</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_bottom</span><span style="color:#85E89D"> span</span><span style="color:#B392F0">.location_tag</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> margin-left</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">5</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_bottom</span><span style="color:#85E89D"> span</span><span style="color:#B392F0">.talk_tag:hover</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_bottom</span><span style="color:#85E89D"> span</span><span style="color:#B392F0">.location_tag:hover</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> box-shadow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">0</span><span style="color:#79B8FF"> 4</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> 8</span><span style="color:#F97583">px</span><span style="color:#79B8FF"> rgba</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">0.3</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_content</span><span style="color:#F97583">></span><span style="color:#85E89D">a</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> margin</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">0</span><span style="color:#79B8FF"> 3</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#ff7d73</span><span style="color:#F97583"> !important</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_content</span><span style="color:#F97583">></span><span style="color:#85E89D">a</span><span style="color:#B392F0">:hover</span><span style="color:#E1E4E8">{</span></span>
<span class="line"><span style="color:#79B8FF"> text-decoration</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">none</span><span style="color:#F97583"> !important</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#ff5143</span><span style="color:#F97583"> !important</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">@media</span><span style="color:#79B8FF"> screen</span><span style="color:#F97583"> and</span><span style="color:#E1E4E8"> (</span><span style="color:#79B8FF">max-width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">900</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#B392F0"> #talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_content</span><span style="color:#B392F0"> .zone_imgbox</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#FFAB70"> --w</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">calc</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">33</span><span style="color:#F97583">%</span><span style="color:#F97583"> -</span><span style="color:#79B8FF"> 5</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#B392F0"> #talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> #post-comment</span><span style="color:#E1E4E8">{</span></span>
<span class="line"><span style="color:#79B8FF"> margin</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">0</span><span style="color:#79B8FF"> 3</span><span style="color:#F97583">px</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#F97583">@media</span><span style="color:#79B8FF"> screen</span><span style="color:#F97583"> and</span><span style="color:#E1E4E8"> (</span><span style="color:#79B8FF">max-width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">768</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#B392F0"> .zone_imgbox</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> gap</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">6</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#B392F0"> .zone_imgbox</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#FFAB70"> --w</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">calc</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">50</span><span style="color:#F97583">%</span><span style="color:#F97583"> -</span><span style="color:#79B8FF"> 3</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#85E89D"> span</span><span style="color:#B392F0">.talk_date</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> font-size</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">14</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_content</span><span style="color:#B392F0"> .douban-card</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> margin-top</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">10</span><span style="color:#F97583">px</span><span style="color:#F97583"> !important</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> text-decoration</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">none</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> align-items</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">center</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> border-radius</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#faebd7</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> display</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">flex</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> justify-content</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">center</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> margin</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">10</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> max-width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">400</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> overflow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">hidden</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> padding</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">15</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> position</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">relative</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.douban-card</span><span style="color:#B392F0"> .douban-card-bgimg</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> background-position</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">50</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> background-repeat</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">no-repeat</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> background-size</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> filter</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">blur</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">15</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">) </span><span style="color:#79B8FF">brightness</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">.6</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> height</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">115</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> position</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">absolute</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">115</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.douban-card</span><span style="color:#B392F0"> .douban-card-left</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> align-items</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">center</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> display</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">flex</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> flex-direction</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">column</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> position</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">relative</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.douban-card</span><span style="color:#B392F0"> .douban-card-left</span><span style="color:#B392F0"> .douban-card-img</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> transition</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">all</span><span style="color:#79B8FF"> .5</span><span style="color:#F97583">s</span><span style="color:#79B8FF"> ease</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> height</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">130</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> position</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">relative</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">80</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> background-position</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">50</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> background-repeat</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">no-repeat</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> background-size</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.douban-card</span><span style="color:#B392F0"> .douban-card-left:hover</span><span style="color:#B392F0"> .douban-card-img</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> filter</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">blur</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">5</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">) </span><span style="color:#79B8FF">brightness</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">.6</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> transform</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">perspective</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">800</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">) </span><span style="color:#79B8FF">rotateX</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">180</span><span style="color:#F97583">deg</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.douban-card</span><span style="color:#B392F0"> .douban-card-right</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">#faebd7</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> display</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">flex</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> flex-direction</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">column</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> font-size</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">14</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> line-height</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">1.5</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> margin-left</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> position</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">relative</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.douban-card</span><span style="color:#B392F0"> .douban-card-right</span><span style="color:#B392F0"> .douban-card-item</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> margin-top</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">4</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> max-width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">95</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> overflow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">hidden</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> text-overflow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">ellipsis</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> white-space</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">nowrap</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">/* 外链卡片 */</span></span>
<span class="line"><span style="color:#B392F0">#talk</span><span style="color:#B392F0"> .talk_item</span><span style="color:#B392F0"> .talk_content</span><span style="color:#B392F0"> .shuoshuo-external-link</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#6A737D"> /* 无下划线 */</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> height</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">80</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> margin-top</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">10</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> border-radius</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> background-color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">var</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">--liushen-card-secondbg</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">var</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">--liushen-card-text</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> border</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">var</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">--liushen-card-border</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> transition</span><span style="color:#E1E4E8">: background-color </span><span style="color:#79B8FF">.3</span><span style="color:#F97583">s</span><span style="color:#79B8FF"> ease-in-out</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.shuoshuo-external-link:hover</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> background-color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">var</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">--liushen-button-hover-bg</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.shuoshuo-external-link</span><span style="color:#B392F0"> .external-link</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> display</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">flex</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">var</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">--liushen-text</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">!important</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> height</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.shuoshuo-external-link</span><span style="color:#B392F0"> .external-link:hover</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> color</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">white</span><span style="color:#F97583"> !important</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.shuoshuo-external-link</span><span style="color:#B392F0"> .external-link:hover</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> text-decoration</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">none</span><span style="color:#F97583"> !important</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.shuoshuo-external-link</span><span style="color:#B392F0"> .external-link-left</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">60</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> height</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">60</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> margin</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">10</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> border-radius</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> background-size</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">cover</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> background-position</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">center</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.shuoshuo-external-link</span><span style="color:#B392F0"> .external-link-right</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> display</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">flex</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> flex-direction</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">column</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> justify-content</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">center</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">calc</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#F97583"> -</span><span style="color:#79B8FF"> 80</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#79B8FF"> padding</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">10</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.shuoshuo-external-link</span><span style="color:#B392F0"> .external-link-right</span><span style="color:#B392F0"> .external-link-title</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> font-size</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">1.0</span><span style="color:#F97583">rem</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> font-weight</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">800</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> white-space</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">nowrap</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> overflow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">hidden</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> text-overflow</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">ellipsis</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.shuoshuo-external-link</span><span style="color:#B392F0"> .external-link-right</span><span style="color:#85E89D"> i</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> margin-left</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">5</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">.limit</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#79B8FF"> width</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">100</span><span style="color:#F97583">%</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> text-align</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">center</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#79B8FF"> margin-top</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">30</span><span style="color:#F97583">px</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span></code></pre>
<p>如果一切正常,应该就可以显示了,但是我在使用时发现卡片是黑色的,把前面的root内容删除之后就好了。</p>
<h1 id="参考内容">参考内容</h1>
<a class="hexo-link-card" href="https://blog.liushen.fun/posts/8338183a/" target="_blank" rel="external nofollow noopener noreferrer">
<span class="hexo-link-card__icon" aria-hidden="true">L</span>
<span class="hexo-link-card__body">
<strong>liushen的博客</strong>
<span>liushen · blog.liushen.fun</span>
</span>
</a>
<p>当然还有chatgpt的支持</p> </div> <section class="post-copyright-card" aria-label="文章版权信息"> <div class="post-copyright-mark" aria-hidden="true"> <span>CC</span> </div> <div class="post-copyright-main"> <h2>配置说说页面</h2> <a class="post-copyright-link" href="/posts/ad244066/">/posts/ad244066/</a> <dl class="post-copyright-meta"> <div> <dt>作者</dt> <dd>biss</dd> </div> <div> <dt>发布于</dt> <dd><time datetime="2025-08-10T08:25:39.000Z">2025/08/10</time></dd> </div> <div> <dt>许可协议</dt> <dd><a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" rel="noreferrer">CC BY-NC-SA 4.0</a></dd> </div> </dl> </div> <div class="post-copyright-footer"> <div class="post-copyright-tags" aria-label="文章标签"> <a href="/tags/%E7%BD%91%E7%AB%99/">网站</a> </div> <div class="post-copyright-actions" aria-label="文章操作"> <button class="post-copyright-action is-primary post-share-button" type="button" data-share-title="配置说说页面" data-share-url="https://blog.biss.click/posts/ad244066/" title="分享文章"> <svg aria-hidden="true" viewBox="0 0 24 24"> <path d="M4 12v7a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-7"></path> <path d="M12 16V4"></path> <path d="m7 9 5-5 5 5"></path> </svg> <span>分享</span> </button> <a class="post-copyright-action" href="/rss.xml" title="订阅 RSS"> <svg aria-hidden="true" viewBox="0 0 24 24"> <path d="M5 5a14 14 0 0 1 14 14"></path> <path d="M5 11a8 8 0 0 1 8 8"></path> <path d="M6 18h.01"></path> </svg> <span>订阅</span> </a> <a class="post-copyright-action" href="/about/" title="打赏作者"> <svg aria-hidden="true" viewBox="0 0 24 24"> <path d="M7 8h10"></path> <path d="M8 8V5h8v3"></path> <path d="M6 8h12l-1.5 11h-9L6 8Z"></path> <path d="M10 12h4"></path> </svg> <span>打赏</span> </a> <a class="post-copyright-icon" href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fblog.biss.click%2Fposts%2Fad244066%2F&amp;text=%E9%85%8D%E7%BD%AE%E8%AF%B4%E8%AF%B4%E9%A1%B5%E9%9D%A2" target="_blank" rel="noreferrer" title="分享到 X"> <span aria-hidden="true">x</span> </a> <a class="post-copyright-icon" href="https://service.weibo.com/share/share.php?url=https%3A%2F%2Fblog.biss.click%2Fposts%2Fad244066%2F&amp;title=%E9%85%8D%E7%BD%AE%E8%AF%B4%E8%AF%B4%E9%A1%B5%E9%9D%A2" target="_blank" rel="noreferrer" title="分享到微博"> <span aria-hidden="true"></span> </a> </div> </div> </section> <script>
(() => {
document.querySelectorAll('.post-share-button').forEach((button) => {
button.addEventListener('click', async () => {
const title = button.dataset.shareTitle || document.title;
const url = button.dataset.shareUrl || window.location.href;
const label = button.querySelector('span');
const originalText = label?.textContent || '分享';
try {
if (navigator.share) {
await navigator.share({ title, url });
return;
}
await navigator.clipboard.writeText(url);
if (label) label.textContent = '已复制';
} catch {
if (label) label.textContent = '复制失败';
} finally {
window.setTimeout(() => {
if (label) label.textContent = originalText;
}, 1800);
}
});
});
})();
</script> <section id="post-comment" class="twikoo-comments" aria-label="Comments" data-env-id="https://comment.biss.click" data-region data-path="/posts/ad244066/" data-script="https://cdn.jsdelivr.net/npm/twikoo@1.7.7/dist/twikoo.min.js"> <div class="twikoo-comments-head"> <span class="twikoo-comments-icon" aria-hidden="true"> <svg viewBox="0 0 24 24"> <path d="M21 12a8 8 0 0 1-8 8H7l-4 3v-5a8 8 0 1 1 18-6Z"></path> </svg> </span> <div> <h2>Comments</h2> <p>配置说说页面</p> </div> </div> <div id="twikoo-wrap" class="twikoo-wrap"></div> </section> <script>
(() => {
const root = document.getElementById('post-comment');
const wrap = document.getElementById('twikoo-wrap');
if (!root || !wrap || root.dataset.twikooLoaded === 'true') return;
const envId = root.dataset.envId;
const path = root.dataset.path || window.location.pathname;
const region = root.dataset.region || undefined;
if (!envId) return;
root.dataset.twikooLoaded = 'true';
const initTwikoo = () => {
if (!window.twikoo || typeof window.twikoo.init !== 'function') return;
window.twikoo.init({
el: wrap,
envId,
region,
path,
});
};
if (window.twikoo) {
initTwikoo();
return;
}
const script = document.createElement('script');
script.src = root.dataset.script;
script.defer = true;
script.onload = initTwikoo;
script.onerror = () => {
root.dataset.twikooLoaded = 'false';
};
document.head.appendChild(script);
})();
</script> </article> <aside class="article-sidebar" aria-label="文章侧边栏"> <section class="sidebar-card article-author-card"> <img class="profile-avatar" src="https://free.picui.cn/free/2025/08/10/689845496a283.png" alt="biss" loading="lazy"> <div class="profile-name">biss</div> <div class="article-author-meta"> <span>2025/08/10</span> <a href="/categories/site-notes/">建站手札</a> </div> </section> <section class="sidebar-card article-tags-card"> <h2> <span aria-hidden="true">#</span>
文章标签
<em>1</em> </h2> <div class="article-tag-list" aria-label="文章标签"> <a href="/tags/%E7%BD%91%E7%AB%99/">#网站</a> </div> </section> <div class="article-sticky-sidebar"> <section class="sidebar-card toc-card"> <h2> <span aria-hidden="true"></span>
文章目录
<em>10</em> </h2> <nav class="toc-list toc-tree" aria-label="文章目录" data-toc-tree> <div class="toc-group is-open" data-toc-group data-heading-id="前期要求"> <a class="toc-link toc-link-main" href="#前期要求" data-toc-link data-toc-top> <span class="toc-marker" aria-hidden="true"></span> <span>前期要求</span> </a> <div class="toc-children" data-toc-children> <a class="toc-link toc-link-child toc-depth-2" href="#硬件要求" data-toc-link> <span>硬件要求</span> </a><a class="toc-link toc-link-child toc-depth-2" href="#软件要求" data-toc-link> <span>软件要求</span> </a> </div> </div><div class="toc-group" data-toc-group data-heading-id="介绍与展示"> <a class="toc-link toc-link-main" href="#介绍与展示" data-toc-link data-toc-top> <span class="toc-marker" aria-hidden="true"></span> <span>介绍与展示</span> </a> </div><div class="toc-group" data-toc-group data-heading-id="部署教程"> <a class="toc-link toc-link-main" href="#部署教程" data-toc-link data-toc-top> <span class="toc-marker" aria-hidden="true"></span> <span>部署教程</span> </a> <div class="toc-children" data-toc-children> <a class="toc-link toc-link-child toc-depth-2" href="#moments部署" data-toc-link> <span>Moments部署</span> </a><a class="toc-link toc-link-child toc-depth-3" href="#compose部署" data-toc-link> <span>Compose部署</span> </a><a class="toc-link toc-link-child toc-depth-3" href="#nginx修改" data-toc-link> <span>Nginx修改</span> </a><a class="toc-link toc-link-child toc-depth-2" href="#前端实现" data-toc-link> <span>前端实现</span> </a> </div> </div><div class="toc-group" data-toc-group data-heading-id="参考内容"> <a class="toc-link toc-link-main" href="#参考内容" data-toc-link data-toc-top> <span class="toc-marker" aria-hidden="true"></span> <span>参考内容</span> </a> </div> </nav> </section> <section class="sidebar-card same-category-card"> <h2> <span aria-hidden="true"></span>
同类文章
<em>8</em> </h2> <div class="same-category-list"> <a href="/posts/8f3b9d21/"> <strong>网站迁移日志</strong> <time datetime="2026-06-19T16:45:00.000Z">2026/06/20</time> </a><a href="/posts/4c91a8f2/"> <strong>用 Umami 分享链接给网站信息卡提供统计数据</strong> <time datetime="2026-06-19T08:58:00.000Z">2026/06/19</time> </a><a href="/posts/7e921903/"> <strong>添加网站左上角菜单</strong> <time datetime="2026-02-10T07:11:14.000Z">2026/02/10</time> </a><a href="/posts/f287c563/"> <strong>添加typesense搜索</strong> <time datetime="2026-02-05T13:14:16.000Z">2026/02/05</time> </a><a href="/posts/b5601a7e/"> <strong>自定义字体</strong> <time datetime="2026-01-16T07:47:15.000Z">2026/01/16</time> </a><a href="/posts/5ed2f1e6/"> <strong>在侧边栏添加日历和倒计时</strong> <time datetime="2026-01-16T07:47:07.000Z">2026/01/16</time> </a><a href="/posts/3a26a97a/"> <strong>为博客添加CMS系统</strong> <time datetime="2025-08-25T22:03:00.000Z">2025/08/26</time> </a><a href="/posts/ce1ec3fe/"> <strong>使用GitHub推送Hexo到服务器</strong> <time datetime="2025-08-18T17:10:18.000Z">2025/08/19</time> </a> </div> </section> <section class="sidebar-card site-info-card" data-site-info-card data-stats-endpoint="https://blogumami.biss.click"> <h2><i class="fa-solid fa-chart-line" aria-hidden="true"></i> 网站信息</h2> <dl class="site-info-list"> <div> <dt>文章数目</dt> <dd>44</dd> </div><div> <dt>本站总字数</dt> <dd>36,128</dd> </div><div> <dt>本站访客数</dt> <dd data-stat-key="visitors">--</dd> </div><div> <dt>本站访问量</dt> <dd data-stat-key="pageviews">--</dd> </div><div> <dt>最后更新时间</dt> <dd>2026/06/20</dd> </div> </dl> </section> <script>
(() => {
const cacheDuration = 10 * 60 * 1000;
const formatter = new Intl.NumberFormat('en-US');
const cards = [...document.querySelectorAll('[data-site-info-card]')];
const endpoint = cards.find((card) => card.dataset.statsEndpoint)?.dataset.statsEndpoint;
if (!endpoint) return;
const cacheKey = `site-info-stats:${endpoint}`;
const updateCards = (stats) => {
const visitors = Number(stats?.visitors);
const pageviews = Number(stats?.pageviews);
cards.forEach((card) => {
const visitorsEl = card.querySelector('[data-stat-key="visitors"]');
const pageviewsEl = card.querySelector('[data-stat-key="pageviews"]');
if (visitorsEl && Number.isFinite(visitors)) visitorsEl.textContent = formatter.format(visitors);
if (pageviewsEl && Number.isFinite(pageviews)) pageviewsEl.textContent = formatter.format(pageviews);
});
};
try {
const cached = JSON.parse(localStorage.getItem(cacheKey) || 'null');
if (cached?.time && Date.now() - cached.time < cacheDuration) {
updateCards(cached.data);
return;
}
} catch {
localStorage.removeItem(cacheKey);
}
fetch(endpoint, { headers: { Accept: 'application/json' } })
.then((response) => {
if (!response.ok) throw new Error(`Stats request failed: ${response.status}`);
return response.json();
})
.then((data) => {
localStorage.setItem(cacheKey, JSON.stringify({ time: Date.now(), data }));
updateCards(data);
})
.catch(() => {
});
})();
</script> </div> </aside> </section> </main> <footer class="site-footer" aria-label="站点页脚"> <div class="footer-inner"> <section class="footer-top" aria-label="站点信息"> <a class="footer-brand" href="/" aria-label="Bi's Blog 首页"> <img src="/images/Bi.ico" alt="" loading="lazy"> <span>Bi&#39;s Blog</span> </a> <p class="footer-slogan">好奇心转化为代码的空间。</p> </section> <section class="footer-contact" aria-label="联系方式"> <p>联系方式</p> <div class="footer-socials"> <a href="mailto:bishsh2006@gmail.com" aria-label="发送邮件" title="发送邮件"> <i class="fa-solid fa-envelope" aria-hidden="true"></i> </a><a href="/rss.xml" aria-label="订阅 RSS" title="订阅 RSS"> <i class="fa-solid fa-rss" aria-hidden="true"></i> </a><a href="https://github.com/bishshi" target="_blank" rel="noreferrer" aria-label="GitHub" title="GitHub"> <i class="fa-brands fa-github" aria-hidden="true"></i> </a> </div> <nav class="footer-contact-links" aria-label="页脚链接"> <a href="/archives/">发展历程</a> <span aria-hidden="true">|</span><a href="/privacy/">隐私政策</a> </nav> </section> <section class="footer-bottom" aria-label="版权信息"> <div> <p>© 2025 - 2026 Bi&#39;s Blog</p> <p>blog.biss.click | 内容采用 CC BY-NC-SA 4.0 协议</p> </div> <div class="footer-meta"> <p>本站已运行:<span id="site-runtime">计算中...</span></p> <p> <a href="https://fastly.com/" target="_blank" rel="noreferrer">Fastly</a> <span aria-hidden="true">|</span><a href="https://astro.build/" target="_blank" rel="noreferrer">ASTRO</a> </p> </div> </section> </div> </footer> <aside class="hitokoto-card is-collapsed" aria-label="一言" data-hitokoto-card data-astro-cid-4cgfuthx> <div class="hitokoto-card__head" data-astro-cid-4cgfuthx> <button class="hitokoto-card__toggle" type="button" aria-label="展开一言" aria-expanded="false" title="一言" data-hitokoto-toggle data-astro-cid-4cgfuthx> <i class="fa-solid fa-quote-left" aria-hidden="true" data-astro-cid-4cgfuthx></i> <span data-astro-cid-4cgfuthx>一言</span> </button> <div class="hitokoto-card__actions" data-astro-cid-4cgfuthx> <button class="hitokoto-card__refresh" type="button" aria-label="换一句" title="换一句" data-hitokoto-refresh data-astro-cid-4cgfuthx> <i class="fa-solid fa-rotate" aria-hidden="true" data-astro-cid-4cgfuthx></i> </button> <button class="hitokoto-card__collapse" type="button" aria-label="收起一言" title="收起" data-hitokoto-collapse data-astro-cid-4cgfuthx> <i class="fa-solid fa-chevron-down" aria-hidden="true" data-astro-cid-4cgfuthx></i> </button> </div> </div> <a class="hitokoto-card__text" href="https://hitokoto.cn/" target="_blank" rel="noreferrer" data-hitokoto-text data-astro-cid-4cgfuthx>
获取中...
</a> <p class="hitokoto-card__from" data-hitokoto-from data-astro-cid-4cgfuthx>来自 Hitokoto</p> </aside> <script type="module">(()=>{const o=document.querySelector("[data-hitokoto-card]"),c=o?.querySelector("[data-hitokoto-toggle]"),s=o?.querySelector("[data-hitokoto-text]"),l=o?.querySelector("[data-hitokoto-from]"),g=o?.querySelector("[data-hitokoto-refresh]"),k=o?.querySelector("[data-hitokoto-collapse]");if(!(o instanceof HTMLElement)||!(c instanceof HTMLButtonElement)||!(s instanceof HTMLAnchorElement)||!(l instanceof HTMLElement))return;const y="https://yiyan.biss.click/api?encode=json",u="hitokoto-card-cache",d="hitokoto-card-expanded",x=360*60*1e3,f={sentence:"生活明朗,万物可爱。",source:"本地缓存",url:"https://hitokoto.cn/"},S=["/","/index.html"].includes(window.location.pathname),w=window.matchMedia("(max-width: 720px)");function E(){try{const t=localStorage.getItem(d);if(t==="true")return!0;if(t==="false")return!1}catch{}return null}function L(t){try{localStorage.setItem(d,String(t))}catch{}}function r(t,{persist:e=!1}={}){o.classList.toggle("is-collapsed",!t),c.setAttribute("aria-expanded",String(t)),c.setAttribute("aria-label",t?"收起一言":"展开一言"),e&&L(t)}function h(){try{const t=localStorage.getItem(u);if(!t)return null;const e=JSON.parse(t);return!e||typeof e.expiresAt!="number"||e.expiresAt<=Date.now()?null:e.data}catch{return null}}function H(t){try{localStorage.setItem(u,JSON.stringify({data:t,expiresAt:Date.now()+x}))}catch{}}function i(t){s.textContent=t.sentence,s.href=t.url||"https://hitokoto.cn/",l.textContent=t.source?`出自 ${t.source}`:"来自 Hitokoto"}async function p({force:t=!1}={}){if(!t){const e=h();if(e){i(e);return}}o.classList.add("is-loading"),s.textContent="获取中...";try{const e=await fetch(y);if(!e.ok)throw new Error(`Hitokoto request failed: ${e.status}`);const n=await e.json(),a=n.hitokoto||n.content||n.sentence||n.text,q=typeof a=="string"&&a.trim()?a.trim():f.sentence,A=typeof n.from=="string"&&n.from.trim()?n.from.trim():"Hitokoto",M=n.uuid?`https://hitokoto.cn/?uuid=${encodeURIComponent(n.uuid)}`:"https://hitokoto.cn/",m={sentence:q,source:A,url:M};H(m),i(m)}catch(e){console.error(e),i(h()||f)}finally{o.classList.remove("is-loading")}}const b=E();r(b??(S&&!w.matches)),c.addEventListener("click",()=>{r(o.classList.contains("is-collapsed"),{persist:!0})}),g?.addEventListener("click",t=>{t.stopPropagation(),r(!0,{persist:!0}),p({force:!0})}),k?.addEventListener("click",t=>{t.stopPropagation(),r(!1,{persist:!0})}),o.addEventListener("click",t=>{o.classList.contains("is-collapsed")&&(t.target instanceof Element&&t.target.closest("a, button")||r(!0,{persist:!0}))}),p()})();</script> <div class="custom-context-menu" data-context-menu role="menu" aria-hidden="true"> <div class="context-menu-nav" aria-label="页面导航"> <button type="button" data-context-action="back" aria-label="后退上一页" title="后退上一页"> <i class="fa-solid fa-arrow-left" aria-hidden="true"></i> </button> <button type="button" data-context-action="forward" aria-label="前进下一页" title="前进下一页"> <i class="fa-solid fa-arrow-right" aria-hidden="true"></i> </button> <button type="button" data-context-action="reload" aria-label="刷新页面" title="刷新页面"> <i class="fa-solid fa-rotate-right" aria-hidden="true"></i> </button> <a href="/" aria-label="返回首页" title="返回首页"> <i class="fa-solid fa-house" aria-hidden="true"></i> </a> </div> <div class="context-menu-group" data-selection-group hidden> <button type="button" data-context-action="copy-selection" data-selection-item> <i class="fa-regular fa-copy" aria-hidden="true"></i> <span>复制选中文字</span> </button> <button type="button" data-context-action="search-selection" data-selection-item> <i class="fa-brands fa-microsoft" aria-hidden="true"></i> <span>用 Bing 搜索</span> </button> <button type="button" data-context-action="quote-selection" data-selection-item data-comments-item> <i class="fa-regular fa-comment-dots" aria-hidden="true"></i> <span>引用到评论区</span> </button> </div> <div class="context-menu-group" data-image-group hidden> <button type="button" data-context-action="copy-image"> <i class="fa-regular fa-image" aria-hidden="true"></i> <span>复制图片</span> </button> <button type="button" data-context-action="open-image"> <i class="fa-solid fa-up-right-from-square" aria-hidden="true"></i> <span>新页面打开图片</span> </button> <button type="button" data-context-action="copy-image-url"> <i class="fa-solid fa-link" aria-hidden="true"></i> <span>复制图片地址</span> </button> </div> <div class="context-menu-group"> <a href="/archives/"> <i class="fa-solid fa-box-archive" aria-hidden="true"></i> <span>时间线</span> </a> <a href="/categories/"> <i class="fa-solid fa-folder" aria-hidden="true"></i> <span>分类</span> </a> <a href="/tags/"> <i class="fa-solid fa-hashtag" aria-hidden="true"></i> <span>标签</span> </a> <button type="button" data-context-action="random-post"> <i class="fa-solid fa-shuffle" aria-hidden="true"></i> <span>&#x968F;&#x673A;&#x6587;&#x7AE0;</span> </button> <button type="button" data-context-action="comments" data-comments-item> <i class="fa-regular fa-comment-dots" aria-hidden="true"></i> <span>跳转评论区</span> </button> <button type="button" data-context-action="print"> <i class="fa-solid fa-print" aria-hidden="true"></i> <span>打印页面</span> </button> <a href="/cc/"> <i class="fa-solid fa-circle-info" aria-hidden="true"></i> <span>网站版权</span> </a> </div> </div> <div class="context-menu-native-hint" data-context-native-hint role="note" aria-label="Ctrl 右键提示"> <kbd>Ctrl</kbd> + &#x53F3;&#x952E;&#xFF1A;&#x6D4F;&#x89C8;&#x5668;&#x539F;&#x751F;&#x83DC;&#x5355;
</div> <script>
(() => {
const menu = document.querySelector('[data-context-menu]');
if (!menu) return;
const nativeHint = document.querySelector('[data-context-native-hint]');
const selectionItems = [...menu.querySelectorAll('[data-selection-item]')];
const selectionGroup = menu.querySelector('[data-selection-group]');
const commentsItems = [...menu.querySelectorAll('[data-comments-item]')];
const imageGroup = menu.querySelector('[data-image-group]');
const focusableSelector = 'a[href], button:not([disabled])';
let lastSelectionText = '';
let lastImage = null;
let nativeHintTimer = 0;
const isNativeContextTarget = (target) =>
target instanceof Element &&
Boolean(target.closest('input, textarea, select, [contenteditable="true"], [contenteditable=""]'));
const getCommentsTarget = () =>
document.querySelector('.twikoo-comments, #twikoo-wrap, #twikoo, .tk-comments-container');
const getSelectionText = () => String(window.getSelection?.() || '').trim();
const getImageTarget = (target) => {
if (!(target instanceof Element)) return null;
const image = target.closest('img');
return image instanceof HTMLImageElement ? image : null;
};
const getImageUrl = () => {
if (!lastImage) return '';
return lastImage.currentSrc || lastImage.src || lastImage.getAttribute('src') || '';
};
const copyText = async (text) => {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
return;
}
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.setAttribute('readonly', '');
textarea.style.position = 'fixed';
textarea.style.inset = '0 auto auto -9999px';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
textarea.remove();
};
const setMenuState = () => {
const hasSelection = lastSelectionText.length > 0;
const hasComments = Boolean(getCommentsTarget());
const hasImage = Boolean(getImageUrl());
selectionItems.forEach((item) => {
item.hidden = !hasSelection;
});
if (selectionGroup) selectionGroup.hidden = !hasSelection;
commentsItems.forEach((item) => {
item.hidden = !hasComments || (item.hasAttribute('data-selection-item') && !hasSelection);
});
if (imageGroup) imageGroup.hidden = !hasImage;
};
const closeMenu = () => {
menu.classList.remove('is-open');
menu.setAttribute('aria-hidden', 'true');
};
const openMenu = (x, y) => {
setMenuState();
menu.classList.add('is-open');
menu.setAttribute('aria-hidden', 'false');
const rect = menu.getBoundingClientRect();
const gap = 10;
const left = Math.min(Math.max(gap, x), window.innerWidth - rect.width - gap);
const top = Math.min(Math.max(gap, y), window.innerHeight - rect.height - gap);
menu.style.left = `${left}px`;
menu.style.top = `${top}px`;
};
const showNativeHint = () => {
if (!nativeHint) return;
window.clearTimeout(nativeHintTimer);
nativeHint.classList.add('is-visible');
nativeHintTimer = window.setTimeout(() => {
nativeHint.classList.remove('is-visible');
}, 2600);
};
const jumpToComments = () => {
const target = getCommentsTarget();
target?.scrollIntoView({ behavior: 'smooth', block: 'start' });
};
const quoteToComments = () => {
jumpToComments();
window.setTimeout(() => {
const textarea = document.querySelector('#twikoo textarea, .twikoo-comments textarea, .tk-input textarea');
if (!(textarea instanceof HTMLTextAreaElement) || !lastSelectionText) return;
const quote = lastSelectionText
.split(/\r?\n/)
.map((line) => `> ${line}`)
.join('\n');
const current = textarea.value.trim();
textarea.value = current ? `${current}\n\n${quote}\n` : `${quote}\n`;
textarea.dispatchEvent(new Event('input', { bubbles: true }));
textarea.focus();
}, 500);
};
const searchSelection = () => {
if (!lastSelectionText) return;
const url = `https://www.bing.com/search?q=${encodeURIComponent(lastSelectionText)}`;
window.open(url, '_blank', 'noopener,noreferrer');
};
const copyImage = async () => {
const imageUrl = getImageUrl();
if (!imageUrl) return;
try {
if (!navigator.clipboard?.write || typeof ClipboardItem === 'undefined') {
throw new Error('Image clipboard is not available.');
}
const response = await fetch(imageUrl, { mode: 'cors' });
const blob = await response.blob();
await navigator.clipboard.write([
new ClipboardItem({ [blob.type || 'image/png']: blob }),
]);
} catch {
await copyText(new URL(imageUrl, window.location.href).toString());
}
};
const openImage = () => {
const imageUrl = getImageUrl();
if (!imageUrl) return;
window.open(new URL(imageUrl, window.location.href).toString(), '_blank', 'noopener,noreferrer');
};
document.addEventListener('contextmenu', (event) => {
if (event.ctrlKey) {
closeMenu();
nativeHint?.classList.remove('is-visible');
return;
}
if (isNativeContextTarget(event.target)) return;
lastSelectionText = getSelectionText();
lastImage = getImageTarget(event.target);
event.preventDefault();
openMenu(event.clientX, event.clientY);
showNativeHint();
});
document.addEventListener('click', (event) => {
const actionTarget = event.target instanceof Element ? event.target.closest('[data-context-action]') : null;
if (!actionTarget || !menu.contains(actionTarget)) {
closeMenu();
return;
}
const action = actionTarget.dataset.contextAction;
closeMenu();
if (action === 'back') history.back();
if (action === 'forward') history.forward();
if (action === 'reload') location.reload();
if (action === 'copy-selection' && lastSelectionText) copyText(lastSelectionText);
if (action === 'search-selection') searchSelection();
if (action === 'quote-selection') quoteToComments();
if (action === 'copy-image') copyImage();
if (action === 'open-image') openImage();
if (action === 'copy-image-url') copyText(new URL(getImageUrl(), window.location.href).toString());
if (action === 'random-post' && typeof window.randomPost === 'function') window.randomPost(actionTarget);
if (action === 'comments') jumpToComments();
if (action === 'print') window.print();
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') closeMenu();
if (event.key === 'Tab' && menu.classList.contains('is-open')) {
const items = [...menu.querySelectorAll(focusableSelector)].filter((item) => !item.closest('[hidden]'));
if (items.length === 0) return;
const first = items[0];
const last = items[items.length - 1];
if (event.shiftKey && document.activeElement === first) {
event.preventDefault();
last.focus();
} else if (!event.shiftKey && document.activeElement === last) {
event.preventDefault();
first.focus();
}
}
});
window.addEventListener('scroll', closeMenu, { passive: true });
window.addEventListener('resize', closeMenu);
})();
</script> <aside class="pwa-toast" data-pwa-toast hidden role="status" aria-live="polite"> <div class="pwa-toast-icon" aria-hidden="true"><i class="fa-solid fa-download"></i></div> <div class="pwa-toast-copy"> <strong data-pwa-title>PWA 提示</strong> <p data-pwa-message></p> </div> <div class="pwa-toast-actions"> <button class="pwa-toast-primary" type="button" data-pwa-primary>确定</button> <button class="pwa-toast-close" type="button" data-pwa-close aria-label="关闭提示">稍后</button> </div> </aside> <script src="https://cdn.jsdmirror.com/npm/instantsearch.js@4.56.0"></script> <script src="https://cdn.jsdmirror.com/npm/typesense-instantsearch-adapter@2.7.0/dist/typesense-instantsearch-adapter.min.js"></script> <script src="https://cdn.jsdmirror.com/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js"></script> <script src="/js/random.js"></script> <script src="/js/search/typesense-search.js"></script> <script src="/js/external-links.js"></script> <script src="/js/pwa.js"></script> <script>
(() => {
const nav = document.querySelector('.nav');
const toggle = document.querySelector('[data-nav-toggle]');
const menu = document.querySelector('[data-nav-menu]');
const backdrop = document.querySelector('[data-nav-backdrop]');
if (!nav || !toggle || !menu) return;
function setMenu(open) {
nav.classList.toggle('is-open', open);
toggle.setAttribute('aria-expanded', String(open));
toggle.setAttribute('aria-label', open ? '关闭菜单' : '打开菜单');
menu.setAttribute('aria-hidden', String(!open && window.innerWidth <= 720));
document.body.classList.toggle('has-nav-drawer', open);
}
toggle.addEventListener('click', () => {
setMenu(!nav.classList.contains('is-open'));
});
backdrop?.addEventListener('click', () => setMenu(false));
menu.addEventListener('click', (event) => {
if (event.target instanceof Element && event.target.closest('a')) setMenu(false);
});
document.addEventListener('click', (event) => {
if (!nav.classList.contains('is-open')) return;
if (event.target instanceof Node && nav.contains(event.target)) return;
setMenu(false);
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape' && nav.classList.contains('is-open')) setMenu(false);
});
window.addEventListener('resize', () => {
if (window.innerWidth > 720) setMenu(false);
else menu.setAttribute('aria-hidden', String(!nav.classList.contains('is-open')));
});
menu.setAttribute('aria-hidden', String(window.innerWidth <= 720));
})();
(() => {
const modal = document.querySelector('[data-console-modal]');
const panel = modal?.querySelector('.control-console-panel');
const openButtons = document.querySelectorAll('[data-console-open]');
const closeButtons = modal?.querySelectorAll('[data-console-close]') || [];
if (!modal || !panel || openButtons.length === 0) return;
function setConsole(open) {
modal.classList.toggle('is-open', open);
modal.setAttribute('aria-hidden', String(!open));
document.body.classList.toggle('has-control-console', open);
if (open) panel.focus();
}
openButtons.forEach((button) => {
button.addEventListener('click', () => setConsole(true));
});
closeButtons.forEach((button) => {
button.addEventListener('click', () => setConsole(false));
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape' && modal.classList.contains('is-open')) setConsole(false);
});
})();
(() => {
const storageKey = 'site-theme';
const root = document.documentElement;
const button = document.querySelector('[data-theme-toggle]');
const media = window.matchMedia('(prefers-color-scheme: dark)');
const getSystemTheme = () => (media.matches ? 'dark' : 'light');
const getSavedTheme = () => {
try {
const theme = localStorage.getItem(storageKey);
return theme === 'dark' || theme === 'light' ? theme : null;
} catch {
return null;
}
};
const setSavedTheme = (theme) => {
try {
if (theme === getSystemTheme()) localStorage.removeItem(storageKey);
else localStorage.setItem(storageKey, theme);
} catch {
// localStorage can be unavailable in strict privacy modes.
}
};
const getTheme = () => getSavedTheme() || getSystemTheme();
function applyTheme(theme) {
root.dataset.theme = theme;
root.dataset.themeMode = getSavedTheme() ? 'manual' : 'auto';
button?.setAttribute('aria-label', theme === 'dark' ? '切换到日间模式' : '切换到夜间模式');
button?.setAttribute(
'title',
getSavedTheme()
? (theme === 'dark' ? '切换到日间模式' : '切换到夜间模式')
: `跟随系统:${theme === 'dark' ? '夜间' : '日间'}模式`
);
}
applyTheme(getTheme());
button?.addEventListener('click', () => {
const nextTheme = root.dataset.theme === 'dark' ? 'light' : 'dark';
setSavedTheme(nextTheme);
applyTheme(nextTheme);
});
const handleSystemThemeChange = () => {
if (!getSavedTheme()) applyTheme(getSystemTheme());
};
if (typeof media.addEventListener === 'function') {
media.addEventListener('change', handleSystemThemeChange);
} else if (typeof media.addListener === 'function') {
media.addListener(handleSystemThemeChange);
}
})();
(() => {
const runtime = document.getElementById('site-runtime');
if (!runtime) return;
const start = new Date(window.SITE_CONFIG.site.startTime).getTime();
const pad = (value) => String(value).padStart(2, '0');
function updateRuntime() {
const diff = Math.max(0, Date.now() - start);
const days = Math.floor(diff / 86400000);
const hours = Math.floor((diff / 3600000) % 24);
const minutes = Math.floor((diff / 60000) % 60);
const seconds = Math.floor((diff / 1000) % 60);
runtime.textContent = `${days}${pad(hours)}${pad(minutes)}${pad(seconds)} 秒`;
}
updateRuntime();
window.setInterval(updateRuntime, 1000);
})();
</script> </body> </html> <script>(function(){const postSlug = "ad244066";
(() => {
const article = document.querySelector('.post-article');
const progressBar = document.querySelector('[data-reading-progress]');
const resume = document.querySelector('[data-reading-resume]');
const resumePercent = document.querySelector('[data-reading-resume-percent]');
const continueButton = document.querySelector('[data-reading-continue]');
const restartButton = document.querySelector('[data-reading-restart]');
if (!article || !progressBar || !resume) return;
const storageKey = `reading-progress:${postSlug}`;
let saved = null;
let canPersist = true;
let frame = 0;
try {
saved = JSON.parse(localStorage.getItem(storageKey) || 'null');
} catch {
saved = null;
}
const articleMetrics = () => {
const top = article.getBoundingClientRect().top + window.scrollY;
const distance = Math.max(1, article.offsetHeight - window.innerHeight);
return { top, distance };
};
const getProgress = () => {
const { top, distance } = articleMetrics();
return Math.min(1, Math.max(0, (window.scrollY - top) / distance));
};
const persist = (progress) => {
if (!canPersist) return;
try {
if (progress >= 0.97) localStorage.removeItem(storageKey);
else if (progress >= 0.02) localStorage.setItem(storageKey, JSON.stringify({ progress, savedAt: Date.now() }));
} catch {
// Storage can be unavailable in strict privacy modes.
}
};
const update = () => {
frame = 0;
const progress = getProgress();
progressBar.style.transform = `scaleX(${progress})`;
persist(progress);
};
const requestUpdate = () => {
if (!frame) frame = window.requestAnimationFrame(update);
};
const closeResume = () => {
resume.hidden = true;
canPersist = true;
};
const savedIsFresh = saved && Date.now() - Number(saved.savedAt) < 90 * 86400000;
const savedProgress = Number(saved?.progress);
if (savedIsFresh && savedProgress >= 0.05 && savedProgress < 0.97) {
canPersist = false;
if (resumePercent) resumePercent.textContent = `${Math.round(savedProgress * 100)}%`;
window.setTimeout(() => { resume.hidden = false; }, 350);
}
continueButton?.addEventListener('click', () => {
closeResume();
const { top, distance } = articleMetrics();
window.scrollTo({ top: top + distance * savedProgress, behavior: 'smooth' });
});
restartButton?.addEventListener('click', () => {
try { localStorage.removeItem(storageKey); } catch {}
closeResume();
window.scrollTo({ top: Math.max(0, articleMetrics().top - 90), behavior: 'smooth' });
});
update();
window.addEventListener('scroll', requestUpdate, { passive: true });
window.addEventListener('resize', requestUpdate);
window.addEventListener('pagehide', () => persist(getProgress()));
})();
})();</script> <script>
(() => {
document.querySelectorAll('.article-outdated-note[data-freshness-at]').forEach((note) => {
const freshnessAt = new Date(note.dataset.freshnessAt || '');
const hasNewVersion = note.dataset.hasNewVersion === 'true';
if (Number.isNaN(freshnessAt.valueOf())) return;
const threshold = new Date();
threshold.setFullYear(threshold.getFullYear() - 1);
note.hidden = !hasNewVersion && freshnessAt >= threshold;
});
})();
</script> <script>
(() => {
const prose = document.querySelector('.prose[data-toc]');
if (!prose) return;
let toc = [];
try {
toc = JSON.parse(prose.dataset.toc || '[]');
} catch {
toc = [];
}
prose.querySelectorAll('h1, h2, h3').forEach((heading, index) => {
const item = toc[index];
if (item?.id && !heading.id) heading.id = item.id;
});
const tocTree = document.querySelector('[data-toc-tree]');
if (tocTree && toc.length > 0) {
const links = [...tocTree.querySelectorAll('[data-toc-link]')];
const groups = [...tocTree.querySelectorAll('[data-toc-group]')];
const headings = toc
.map((item) => document.getElementById(item.id))
.filter(Boolean);
const setActiveToc = (id) => {
links.forEach((link) => {
const isActive = link.getAttribute('href') === `#${id}`;
link.classList.toggle('is-active', isActive);
if (isActive) link.setAttribute('aria-current', 'location');
else link.removeAttribute('aria-current');
});
const activeLink = tocTree.querySelector(`[data-toc-link][href="#${CSS.escape(id)}"]`);
const activeGroup = activeLink?.closest('[data-toc-group]');
groups.forEach((group) => group.classList.toggle('is-open', group === activeGroup));
};
const updateToc = () => {
const anchorOffset = 132;
let activeId = headings[0]?.id;
headings.forEach((heading) => {
if (heading.getBoundingClientRect().top <= anchorOffset) activeId = heading.id;
});
if (activeId) setActiveToc(activeId);
};
tocTree.addEventListener('click', (event) => {
const link = event.target.closest?.('[data-toc-link]');
if (!link) return;
const group = link.closest('[data-toc-group]');
groups.forEach((item) => item.classList.toggle('is-open', item === group));
});
updateToc();
window.addEventListener('scroll', updateToc, { passive: true });
window.addEventListener('resize', updateToc);
}
})();
</script> <script>
(() => {
const prose = document.querySelector('.post-article .prose');
if (!prose) return;
const collapsedLineCount = 8;
const copyLabels = {
idle: '复制',
done: '已复制',
error: '复制失败',
};
const languageNames = {
bash: 'Bash',
c: 'C',
cpp: 'C++',
cs: 'C#',
css: 'CSS',
html: 'HTML',
js: 'JavaScript',
json: 'JSON',
jsx: 'JSX',
md: 'Markdown',
powershell: 'PowerShell',
py: 'Python',
shell: 'Shell',
sh: 'Shell',
ts: 'TypeScript',
tsx: 'TSX',
txt: 'Text',
yaml: 'YAML',
yml: 'YAML',
};
function getCodeLanguage(pre, code) {
const rawLanguage =
pre.dataset.language ||
code.dataset.language ||
[...pre.classList, ...code.classList]
.find((className) => className.startsWith('language-'))
?.replace(/^language-/, '') ||
'';
const normalized = rawLanguage.trim().toLowerCase();
return languageNames[normalized] || normalized.toUpperCase() || 'Code';
}
function getCodeText(code, lines) {
if (lines.length > 0) return lines.map((line) => line.textContent || '').join('\n');
return code.textContent || '';
}
prose.querySelectorAll('img').forEach((image) => {
if (image.closest('a, .article-header-cover')) return;
const src = image.currentSrc || image.getAttribute('src');
if (!src) return;
const link = document.createElement('a');
link.className = 'fancybox';
link.href = src;
link.dataset.fancybox = 'article-gallery';
link.dataset.caption = image.getAttribute('alt') || '';
image.parentNode?.insertBefore(link, image);
link.appendChild(image);
});
prose.querySelectorAll('table').forEach((table) => {
if (table.closest('.table-scroll')) return;
const wrapper = document.createElement('div');
wrapper.className = 'table-scroll';
table.parentNode?.insertBefore(wrapper, table);
wrapper.appendChild(table);
});
prose.querySelectorAll('.butterfly-hide-inline').forEach((item) => {
const button = item.querySelector('.butterfly-hide-toggle');
if (!button) return;
button.addEventListener('click', () => {
item.classList.toggle('is-open');
});
});
if (window.Fancybox) {
window.Fancybox.bind('[data-fancybox="article-gallery"]', {
compact: false,
dragToClose: true,
Images: {
zoom: true,
},
});
}
async function copyText(text) {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
return;
}
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.setAttribute('readonly', '');
textarea.style.position = 'fixed';
textarea.style.top = '-9999px';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
textarea.remove();
}
prose.querySelectorAll('pre').forEach((pre) => {
if (pre.closest('.code-block')) return;
const code = pre.querySelector('code');
if (!code) return;
const wrapper = document.createElement('div');
wrapper.className = 'code-block';
pre.parentNode?.insertBefore(wrapper, pre);
wrapper.appendChild(pre);
const header = document.createElement('div');
header.className = 'code-block-header';
const language = document.createElement('span');
language.className = 'code-block-language';
language.textContent = getCodeLanguage(pre, code);
const toolbar = document.createElement('div');
toolbar.className = 'code-block-toolbar';
const copyButton = document.createElement('button');
copyButton.className = 'code-block-copy';
copyButton.type = 'button';
copyButton.textContent = copyLabels.idle;
copyButton.setAttribute('aria-label', '复制代码');
const toggleButton = document.createElement('button');
toggleButton.className = 'code-block-toggle';
toggleButton.type = 'button';
toggleButton.textContent = '展开';
toggleButton.setAttribute('aria-expanded', 'false');
const expandCue = document.createElement('button');
expandCue.className = 'code-block-expand-cue';
expandCue.type = 'button';
expandCue.setAttribute('aria-label', 'Expand code block');
expandCue.setAttribute('aria-expanded', 'false');
expandCue.innerHTML = '<span aria-hidden="true"></span>';
toolbar.append(copyButton, toggleButton);
header.append(language, toolbar);
wrapper.appendChild(header);
wrapper.appendChild(expandCue);
const codeLines = [...code.querySelectorAll(':scope > .line')];
if (codeLines.length > 0) {
wrapper.classList.add('has-line-numbers');
wrapper.style.setProperty('--line-number-width', `${String(codeLines.length).length + 1}ch`);
codeLines.forEach((line, index) => {
line.dataset.line = String(index + 1);
});
}
const lineCount = codeLines.length || (code.textContent || '').split(/\r?\n/).length;
if (lineCount > collapsedLineCount) wrapper.classList.add('is-collapsible');
copyButton.addEventListener('click', async () => {
try {
await copyText(getCodeText(code, codeLines));
copyButton.textContent = copyLabels.done;
window.setTimeout(() => {
copyButton.textContent = copyLabels.idle;
}, 1400);
} catch {
copyButton.textContent = copyLabels.error;
window.setTimeout(() => {
copyButton.textContent = copyLabels.idle;
}, 1600);
}
});
function toggleExpanded() {
const isExpanded = wrapper.classList.toggle('is-expanded');
toggleButton.textContent = isExpanded ? '收起' : '展开';
toggleButton.setAttribute('aria-expanded', String(isExpanded));
expandCue.setAttribute('aria-expanded', String(isExpanded));
}
toggleButton.addEventListener('click', toggleExpanded);
expandCue.addEventListener('click', toggleExpanded);
});
})();
</script>