<!DOCTYPE html><html lang="zh" data-theme="dark"><head><meta charset="utf-8"><meta name="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>观《疯狂动物城 2》 · Cytrogen 的个人博客</title><meta name="description" content="上个月一直想看的《疯狂动物城 2》,最近终于有时间去和室友一起看了。和 上次 一样,我去的还是周二三场。毕竟才 10 块钱。"><link rel="icon" href="../favicon.png"><link rel="canonical" href="https://cytrogen.icu/posts/7240.html"><link rel="webmention" href="https://webmention.io/cytrogen.icu/webmention"><link rel="me" href="https://m.otter.homes/@Cytrogen"><link rel="me" href="https://github.com/cytrogen"><meta name="fediverse:creator" content="@Cytrogen@m.otter.homes"><link rel="preload" href="../fonts/opensans-regular-latin.woff2" as="font" type="font/woff2" crossorigin="anonymous"><style>@font-face {
font-family: 'Open Sans';
src: url('../fonts/opensans-regular-latin.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
size-adjust: 107%;
ascent-override: 97%;
descent-override: 25%;
line-gap-override: 0%;
}
</style><script>(function() {
try {
// 优先级:用户选择 > 系统偏好 > 默认浅色
const saved = localStorage.getItem('theme');
const theme = saved ||
(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);
document.documentElement.style.colorScheme = theme;
} catch (error) {
// 失败时使用默认主题,不阻塞渲染
document.documentElement.setAttribute('data-theme', 'light');
}
})();
</script><link rel="stylesheet" href="../css/ares.css"><script data-netlify-skip-bundle="true">(function() {
document.addEventListener('DOMContentLoaded', function() {
const theme = document.documentElement.getAttribute('data-theme');
const pageWrapper = document.getElementById('page-wrapper');
if (pageWrapper && theme) {
pageWrapper.setAttribute('data-theme', theme);
}
});
})();
</script><!-- hexo injector head_end start -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/hexo-math@4.0.0/dist/style.css">
<!-- hexo injector head_end end --><meta name="generator" content="Hexo 8.1.1"><link rel="alternate" href="atom.xml" title="Cytrogen 的个人博客" type="application/atom+xml">
</head><body><div id="page-wrapper"><a class="skip-link" href="#main-content">跳到主要内容</a><div class="wrap"><header><a class="logo-link" href="../index.html"><img src="../favicon.png" alt="logo"></a><div class="h-card visually-hidden"><img class="u-photo" src="https://cytrogen.icu/favicon.png" alt="Cytrogen"><a class="p-name u-url u-uid" href="https://cytrogen.icu">Cytrogen</a><p class="p-note">Cytrogen 的个人博客,Cytrogen's Blog</p><a class="u-url" rel="me noopener" target="_blank" href="https://m.otter.homes/@Cytrogen">Mastodon</a><a class="u-url" rel="me noopener" target="_blank" href="https://github.com/cytrogen">GitHub</a></div><nav class="site-nav"><div class="nav-main"><div class="nav-primary"><ul class="nav-list hidden-mobile"><li class="nav-item"><a class="nav-link" href="../index.html">首页</a></li></ul><div class="nav-tools"><div class="language-menu"><button class="language-toggle" type="button"><svg class="icon icon-globe" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm7.5-6.923c-.67.204-1.335.82-1.887 1.855A7.97 7.97 0 0 0 5.145 4H7.5V1.077zM4.09 4a9.267 9.267 0 0 1 .64-1.539 6.7 6.7 0 0 1 .597-.933A7.025 7.025 0 0 0 2.255 4H4.09zm-.582 3.5c.03-.877.138-1.718.312-2.5H1.674a6.958 6.958 0 0 0-.656 2.5h2.49zM4.847 5a12.5 12.5 0 0 0-.338 2.5H7.5V5H4.847zM8.5 5v2.5h2.99a12.495 12.495 0 0 0-.337-2.5H8.5zM4.51 8.5a12.5 12.5 0 0 0 .337 2.5H7.5V8.5H4.51zm3.99 0V11h2.653c.187-.765.306-1.608.338-2.5H8.5zM5.145 12c.138.386.295.744.468 1.068.552 1.035 1.218 1.65 1.887 1.855V12H5.145zm.182 2.472a6.696 6.696 0 0 1-.597-.933A9.268 9.268 0 0 1 4.09 12H2.255a7.024 7.024 0 0 0 3.072 2.472zM3.82 11a13.652 13.652 0 0 1-.312-2.5h-2.49c.062.89.291 1.733.656 2.5H3.82zm6.853 3.472A7.024 7.024 0 0 0 13.745 12H11.91a9.27 9.27 0 0 1-.64 1.539 6.688 6.688 0 0 1-.597.933zM8.5 12v2.923c.67-.204 1.335-.82 1.887-1.855A7.97 7.97 0 0 0 10.855 12H8.5zm3.68-1h2.146c.365-.767.594-1.61.656-2.5h-2.49a13.65 13.65 0 0 1-.312 2.5zm2.802-3.5a6.959 6.959 0 0 0-.656-2.5H12.18c.174.782.282 1.623.312 2.5h2.49zM11.27 2.461c.247.464.462.98.64 1.539h1.835a7.024 7.024 0 0 0-3.072-2.472c.218.284.418.598.597.933zM10.855 4a7.966 7.966 0 0 0-.468-1.068C9.835 1.897 9.17 1.282 8.5 1.077V4h2.355z"></path></svg><span>中文</span></button><div class="language-dropdown"></div></div></div><div class="nav-controls"><div class="more-menu hidden-mobile"><button class="more-toggle" type="button"><span>更多</span><svg class="icon icon-chevron-down" width="12" height="12" viewBox="0 0 12 12" fill="currentColor" aria-hidden="true" focusable="false"><path d="M6 8.825c-.2 0-.4-.1-.5-.2l-3.3-3.3c-.3-.3-.3-.8 0-1.1s.8-.3 1.1 0l2.7 2.7 2.7-2.7c.3-.3.8-.3 1.1 0s.3.8 0 1.1l-3.3 3.3c-.1.1-.3.2-.5.2z"></path></svg></button><div class="more-dropdown"><ul class="dropdown-list"><li class="dropdown-item"><a class="nav-link" href="../archives/index.html">归档</a></li><li class="dropdown-item"><a class="nav-link" href="../categories/index.html">分类</a></li><li class="dropdown-item"><a class="nav-link" href="../tags/index.html">标签</a></li><li class="dropdown-item"><a class="nav-link" href="../about/index.html">关于</a></li><li class="dropdown-item"><a class="nav-link" href="../sitemap/index.html">领地地图</a></li></ul></div></div><div class="theme-switcher"><button class="theme-toggle" type="button" role="switch" aria-pressed="false" aria-label="切换主题"><div class="theme-icon moon-icon"><svg class="icon icon-moon" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"></path></svg></div><div class="theme-icon sun-icon"><svg class="icon icon-sun" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"></path></svg></div></button></div><details class="mobile-menu-details hidden-desktop"><summary class="hamburger-menu" aria-label="nav.menu"><svg class="icon icon-bars" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"></path></svg><span class="menu-text">nav.menu</span></summary><div class="mobile-menu-dropdown"><ul class="mobile-nav-list"><li class="mobile-nav-item"><a class="mobile-nav-link" href="../index.html">首页</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../archives/index.html">归档</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../categories/index.html">分类</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../tags/index.html">标签</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../about/index.html">关于</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../sitemap/index.html">领地地图</a></li></ul></div></details></div></div></div></nav></header><main class="container" id="main-content" tabindex="-1"><div class="post"><article class="post-block h-entry"><div class="post-meta p-author h-card visually-hidden"><img class="author-avatar u-photo" src="../favicon.png" alt="Cytrogen"><span class="p-name">Cytrogen</span><a class="u-url" href="https://cytrogen.icu">https://cytrogen.icu</a></div><a class="post-permalink u-url u-uid visually-hidden" href="https://cytrogen.icu/posts/7240.html">永久链接</a><div class="p-summary visually-hidden"><p>上个月一直想看的《疯狂动物城 2》,最近终于有时间去和室友一起看了。和 <a href="/posts/5097.HTML">上次</a> 一样,我去的还是周二三场。毕竟才 10 块钱。</p></div><div class="visually-hidden"><a class="p-category" href="../categories/%E5%BD%B1%E8%AF%84/">影评</a></div><h1 class="post-title p-name">观《疯狂动物城 2》</h1><div class="post-info"><time class="post-date dt-published" datetime="2025-12-27T19:59:48.000Z">12/27/2025</time><time class="dt-updated visually-hidden" datetime="2026-02-09T17:16:55.549Z"></time></div><div class="post-content e-content"><html><head></head><body><p>上个月一直想看的《疯狂动物城 2》,最近终于有时间去和室友一起看了。和 <a href="/posts/5097.html">上次</a> 一样,我去的还是周二三场。毕竟才 10 块钱。</p>
<span id="more"></span>
<div class="danger warning"><p>不想要被剧透的还是不要看了吧 —— 虽然话是这么说的,但如果你都不想被剧透了,还点进来做什么呢?</p>
</div>
<p>去家附近的影院之前,我和室友在美式中餐馆里快速吃了炒面和炒粉,期间还玩了 Neal 的 <a target="_blank" rel="noopener" href="https://neal.fun/absurd-trolley-problems/"><em>Absurd Trolley Problems</em></a>(荒诞电车难题)游戏。她认为,在不认识任何人的情况下,一切都应当遵守「少数服从多数」的规矩,而人优先于任何非人或者非生命,并且交易是不可取的。如果绑在铁轨上的人是我的话,她会选择让其他人死。</p>
<p>因为对「少数服从多数」规矩的严格遵守,就算是第 9 关里那五个人是「自杀者」,她也会选择救下他们、杀死那一个不想死的人。</p>
<p>这次去的影院要比上次去的明显大不少。我们没有买爆米花和饮料,直接入了场。令人大跌眼镜的是,买的位置被别人坐去了。</p>
<p>本来想着去其他位置坐也行,避免冲突。但后来一想,首先我买的位置是整个影院里最好的位置,其次要是坐到了其他人买的位置怎么办?最后室友替我去沟通,让这群小孩回到了他们该在的位置。</p>
<p>因为晚来了十分钟,不需要看那又臭又长的广告,可以直接观看其他电影的预告片。我发现根据看的电影类型,播放的预告片类型也不同,这次没有任何恐怖电影的预告片,都是合家欢或者以动物为主角的电影。</p>
<p>我特别喜欢看这类「给儿童看的电影」,未来或许会去看《山羊巅峰》和主角特别可爱的《河狸变身计划》。</p>
<h2 id="电影中"><a class="markdownIt-Anchor" href="#电影中"></a> 电影中</h2>
<p>先说结论,我认为这部电影一路看下来没有什么很大的毛病。</p>
<p>里面穿插了许多让人会心一笑的桥段,例如对《料理鼠王》的致敬,甚至还有后期对《闪灵》的致敬 —— 你这个合家欢电影致敬它真的没问题吗!</p>
<p>动物们的模型依旧很可爱,尤其是狼:大鼻子、长长的嘴筒子,很多时候还会瞪个大眼睛,实在是太可爱了。片中有两个山羊警官,一直戴着个墨镜,特别骚气。</p>
<p>这次电影里也展示了第一部没有出现的动物,比方说在水里生活的动物,补充了「鱼类」在这个世界观里的定位 —— 拿去吃。</p>
<p>这种设定我会更喜欢《动物狂想曲》的,鱼类也是生命,但是他们的观念是「吃」这一行为不过是大自然的一部分。你吃了我,你也会被其他更大的生物吃,而更大的生物一旦死去,便是滋润了无数小生物的「鲸落」。</p>
<p>电影开头的「毛毛心理咨询」实在是太 America 了。我身边的人几乎都做过心理咨询,不过我自己没做过,我光是听他们描述的我就不想去。</p>
<p>通常来说,电影的剧情架构是这样的:</p>
<ol>
<li>引入冲突</li>
<li>引入主线和新伙伴</li>
<li>线性推进主线</li>
<li>被背叛</li>
<li>解决主线问题</li>
<li>解决最初引入的冲突</li>
</ol>
<p>第一部里,冲突是「社会对动物们所添加的标签」,旨在告诉观众「谁都可以成为任何人」。刻画该冲突的方式便是刻画朱迪作为一个警官有被多么忽视,以及尼克作为一只狐狸被包括朱迪在内的人投射刻板印象。其实说是冲突,更像是整个《疯狂动物城》系列的主题,只是第一部里着重刻画了它。</p>
<p>第二部的主题更复杂,原有主题依然存在,不过朱迪和尼克的关系也成为了一种冲突。</p>
<p>朱迪作为理想主义者,她可以为了自己的理想做任何事,为了刻画这一点,朱迪的行为变得更加鲁莽。尼克很关心朱迪,成为警官也是为了和朱迪在一起,但是他无法表达出这一点,可能是好面子。</p>
<p>我个人认为,他们中期吵架的那一部分做的不够好。</p>
<p>朱迪为了追盖瑞、毫不犹豫地跳入了水管内,差点窒息而亡,最后是尼克救了她。朱迪很不开心,认为这错失了追盖瑞的机会;尼克也很不开心,他只是想要朱迪好好的,为此他愿意和朱迪一起放弃身份、逃离动物城,在哪个角落里安安稳稳过日子。</p>
<p>问题在于,冲突应当是两个角色都做错了事情,才能在最后通过道歉达成和解。</p>
<p>我们可以具体拆一下:</p>
<p>朱迪的问题是:</p>
<ul>
<li>行为鲁莽、不顾生命危险</li>
<li>被救后反而指责尼克</li>
<li>爬山时录音笔摔坏,选择回避情绪冲突</li>
<li>在旅店里只想取证据,不关心尼克的恐慌</li>
</ul>
<p>尼克的问题则相对单一:</p>
<ul>
<li>想要和朱迪在一起</li>
<li>不希望朱迪受伤</li>
<li>但始终没有表达自己的真实感受</li>
</ul>
<p>这样一看,冲突明显不平衡。</p>
<p>然而在结尾,率先道歉的是尼克。</p>
<p>我很喜欢第一部的一幕是朱迪从老家回来找尼克,并且真诚地向尼克道歉。我原本期待,第二部里可以是朱迪更清除地意识到自己的问题,并主动迈出那一步。</p>
<p>用我在网络上看到的一句话是:</p>
<blockquote>
<p>朱迪没有成长,尼克只是看开了。</p>
</blockquote>
<p>当然,说是没有成长就有点夸大了。</p>
<p>然后便是续作几乎一定会出现的新主线和新伙伴。</p>
<p>第二部的主线是帮助盖瑞找回自己的家园,并且击溃林雪猁家族的阴谋。说实话,在美国看林雪猁家族的阴谋,实在是让人如坐针毡。这也太像美国人赶走印第安人和墨西哥人的历史了吧!理由也很简单,因为他们是领地动物,所以他们想要赶走其他动物,扩张自己的领地。</p>
<p>好吧,现实中那么多可悲的历史,理由说不定也是这么简单。</p>
<p>中间的线性推进主线我就不说了,基本上就是展示世界观。直接来看「背叛」。</p>
<p>第一部里朱迪被羊副市长背叛,颠覆了「食草动物是弱势」的刻板印象。观众和朱迪一样,被迫意识到「加害者与被害者」的区分并不来自物种,而来自权力、位置与选择。</p>
<p>食肉动物很强很可怕吗?但是他们在社会里很难做到一些事情。朱迪作为「弱势群体」警校毕业就能受到羊副市长的支持、来动物城工作,但是作为「强势群体」的尼克呢?他从来都没有选择。</p>
<p>第二部里,朱迪则被宝伯特背叛,此时的主题依然是「变成刻板印象里不一样的样子」,宝伯特的回应是「但我不想要和家人不一样」。</p>
<p>这个背叛和第一部的背叛有着本质上的差异:它没有颠覆任何主题层面的既有认知,它只是角色立场的转向。我们知道了宝伯特为什么会这么做,但是没有迫使我们重新思考「我们原先相信的是否是错的」。这也使得这一段情节在情感和思想上的冲击力,明显弱于第一部。</p>
<p>我自己很不喜欢第二部里如何解决这些冲突的方式。</p>
<p>在朱迪和尼克解开心结后,整个故事突然开始以过山车般的方式一路冲向地底:先前作为傀儡的马飞扬突然决定不再听从林雪猁家族;宝伯特越来越疯狂,却又被轻易击败;盖瑞找到了专利证明,林雪猁家族锒铛入狱。</p>
<p>一切结束得太快了。</p>
<p>电影的结尾出现了羽毛的彩蛋,貌似第三部会出现鸟类动物。</p>
<p>结束后,室友跟我说的第一句话是,「感觉怪怪的,没有第一部那么惊艳。」</p>
<p>我认为电影续作确实很难达到首作的高度。因为首作是围绕着主题所展开的,而续作要操心更多事情:让旧角色登场、维持系列主题、引入新故事、制造新冲突……</p>
<p>我认为创作里,第一条是最不重要的。但电影依然做了这一点,让许多角色回归,虽然观感很差,但也照顾到了这些角色的粉丝们。</p>
<h2 id="电影后"><a class="markdownIt-Anchor" href="#电影后"></a> 电影后</h2>
<p>我和室友看了许多解析视频,来了解我们心中的不快。</p>
<p>其中我认为做的最好的是这个视频:<a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1STSyBFE8u">为何尼克绝不该只为爱情而生?为何马市长是 2 最大遗憾?深度解析疯狂动物城系列!</a> 视频里很棒地解释了为什么第一部那么出彩:它讨论的并不只是「有没有歧视」,而是 <strong>谁被定义为弱势,以及这种定义是如何运作的</strong> —— 食草动物与食肉动物、看得见的冲突与看不见的身份红利。</p>
<p>第一部真正厉害的地方,并不只是展示了朱迪作为「食草动物」视角下的动物城歧视,还同时给出了尼克作为「食肉动物」所承受的另一套歧视逻辑。这两种视角并不是简单的对立,而是相互错位的:朱迪从小被当作弱势的一方被忽视、被低估,于是她理所当然地认为「食草动物就是弱势群体」;而尼克看起来体格更大、更具威胁性,却在制度和信任层面被系统性地排除在外。</p>
<p>这也使得朱迪这个角色变得更加复杂。她确实遭遇过歧视,但她同样明显拥有身份红利:她是食草动物、是警察、是体制内的「成功案例」。而她对这种红利几乎是完全无意识的 —— 直到那场发布会的发言伤害了尼克,她才第一次意识到,自己口中「理所当然的判断」,在尼克那里意味着什么。</p>
<p>第一部里那些体格庞大的食肉动物,正是在这里显露出他们的脆弱:在权力结构面前,体型、力量、凶猛都毫无意义,他们只是另一种层面下的弱势群体。也正是因为这种多层次、交错的弱势描写,第一部的主题才显得如此扎实。</p>
<p>相比之下,第二部虽然引入了爬行动物作为新的伙伴,却给到他们的篇幅实在太少,少到我在回想剧情时,甚至会暂时忘记他们的存在。这一点让我觉得有些可惜。</p>
<p>Claire 也在视频中提到了一些她认为遗憾的地方:很多原本可以继续深挖的议题,最后都只是轻轻擦过,没有再往前走一步。</p>
<p>最后便是关于朱迪和尼克之间的关系。</p>
<p>我认为他们有着亲密关系,但这不一定是爱情,因为亲密关系本身就不等同于爱情。</p>
<p>这个命题也是我现实生活中一直在探讨的:我可以有一个生命中最亲密最重要的人,但我们之间没有爱情,我们有的只是陪伴和理解彼此。</p>
<p>我渴望拥有这样的关系,但是这很难。</p>
</body></html></div></article></div></main><footer><div class="paginator"><a class="prev" href="18b0.html">上一篇</a><a class="next" href="6e69.html">下一篇</a></div><!-- Webmention 显示区域--><div class="webmention-section webmention-empty" data-page-url="posts/7240.html" data-full-url="https://cytrogen.icu/posts/7240.html" data-mode="static">
<h3 class="webmention-title">Webmentions (<span class="webmention-count">0</span>)</h3>
<div class="webmention-list"></div>
<span>暂无 Webmentions</span>
</div><div class="copyright"><p class="footer-links"><a href="../friends/index.html">友链</a><span class="footer-separator"> ·</span><a href="../links/index.html">邻邦</a><span class="footer-separator"> ·</span><a href="../contact/index.html">联络</a><span class="footer-separator"> ·</span><a href="../colophon/index.html">营造记</a><span class="footer-separator"> ·</span><a href="../atom.xml">RSS订阅</a></p><p>© 2025 - 2026 <a href="https://cytrogen.icu">Cytrogen</a>, powered by <a href="https://hexo.io/" target="_blank">Hexo</a> and <a href="https://github.com/cytrogen/hexo-theme-ares" target="_blank">hexo-theme-ares</a>.</p><p><a href="https://blogscn.fun" target="_blank" rel="noopener">BLOGS·CN</a></p></div></footer></div></div><a class="back-to-top" href="#top" aria-label="返回顶部"><svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path d="M3.293 9.707a1 1 0 010-1.414L9.586 2a2 2 0 012.828 0l6.293 6.293a1 1 0 01-1.414 1.414L11 3.414V17a1 1 0 11-2 0V3.414L2.707 9.707a1 1 0 01-1.414 0z"></path></svg></a><script>document.addEventListener('DOMContentLoaded', function() {
const codeBlocks = document.querySelectorAll('figure.highlight');
codeBlocks.forEach(block => {
let caption = block.querySelector('figcaption');
if (!caption) {
caption = document.createElement('figcaption');
block.insertBefore(caption, block.firstChild);
}
const info = document.createElement('div');
info.className = 'info';
const filename = caption.querySelector('span');
if (filename) {
filename.className = 'filename';
info.appendChild(filename);
}
const lang = block.className.split(' ')[1];
if (lang) {
const langSpan = document.createElement('span');
langSpan.className = 'lang-name';
langSpan.textContent = lang;
info.appendChild(langSpan);
}
const sourceLink = caption.querySelector('a');
if (sourceLink) {
sourceLink.className = 'source-link';
info.appendChild(sourceLink);
}
const actions = document.createElement('div');
actions.className = 'actions';
const codeHeight = block.scrollHeight;
const threshold = 300;
if (codeHeight > threshold) {
block.classList.add('folded');
const toggleBtn = document.createElement('button');
toggleBtn.textContent = '展开';
toggleBtn.addEventListener('click', () => {
block.classList.toggle('folded');
toggleBtn.textContent = block.classList.contains('folded') ? '展开' : '折叠';
});
actions.appendChild(toggleBtn);
}
const copyBtn = document.createElement('button');
copyBtn.textContent = '复制';
copyBtn.addEventListener('click', async () => {
const codeLines = block.querySelectorAll('.code .line');
const code = Array.from(codeLines)
.map(line => line.textContent)
.join('\n')
.replace(/\n\n/g, '\n');
try {
await navigator.clipboard.writeText(code);
copyBtn.textContent = '已复制';
copyBtn.classList.add('copied');
setTimeout(() => {
copyBtn.textContent = '复制';
copyBtn.classList.remove('copied');
}, 3000);
} catch (err) {
console.error('复制失败:', err);
copyBtn.textContent = '复制失败';
setTimeout(() => {
copyBtn.textContent = '复制';
}, 3000);
}
});
actions.appendChild(copyBtn);
caption.innerHTML = '';
caption.appendChild(info);
caption.appendChild(actions);
const markedLines = block.getAttribute('data-marked-lines');
if (markedLines) {
const lines = markedLines.split(',');
lines.forEach(range => {
if (range.includes('-')) {
const [start, end] = range.split('-').map(Number);
for (let i = start; i <= end; i++) {
const line = block.querySelector(`.line-${i}`);
if (line) line.classList.add('marked');
}
} else {
const line = block.querySelector(`.line-${range}`);
if (line) line.classList.add('marked');
}
});
}
});
});</script><script async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" id="MathJax-script"></script><script>(function() {
document.addEventListener('DOMContentLoaded', function() {
const themeToggle = document.querySelector('.theme-toggle');
if (!themeToggle) return;
const getCurrentTheme = () => {
return document.documentElement.getAttribute('data-theme') || 'light';
};
const updateUI = (theme) => {
const isDark = theme === 'dark';
themeToggle.setAttribute('aria-pressed', isDark.toString());
};
const setTheme = (theme) => {
document.documentElement.setAttribute('data-theme', theme);
document.documentElement.style.colorScheme = theme;
const pageWrapper = document.getElementById('page-wrapper');
if (pageWrapper) {
pageWrapper.setAttribute('data-theme', theme);
}
// Find and remove the temporary anti-flicker style tag if it exists.
// This ensures the main stylesheet takes full control after the initial load.
const antiFlickerStyle = document.getElementById('anti-flicker-style');
if (antiFlickerStyle) {
antiFlickerStyle.remove();
}
localStorage.setItem('theme', theme);
updateUI(theme);
};
const toggleTheme = () => {
const current = getCurrentTheme();
const newTheme = current === 'light' ? 'dark' : 'light';
setTheme(newTheme);
};
updateUI(getCurrentTheme());
themeToggle.addEventListener('click', toggleTheme);
if (window.matchMedia) {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
mediaQuery.addEventListener('change', function(e) {
if (!localStorage.getItem('theme')) {
const theme = e.matches ? 'dark' : 'light';
setTheme(theme);
}
});
}
});
})();
</script><script src="../js/details-toggle.js" defer></script><script>(function() {
document.addEventListener('DOMContentLoaded', function() {
const backToTopBtn = document.querySelector('.back-to-top');
if (!backToTopBtn) return;
const toggleButtonVisibility = () => {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const shouldShow = scrollTop > 200;
if (shouldShow) {
backToTopBtn.classList.add('is-visible');
} else {
backToTopBtn.classList.remove('is-visible');
}
};
let ticking = false;
const handleScroll = () => {
if (!ticking) {
requestAnimationFrame(() => {
toggleButtonVisibility();
ticking = false;
});
ticking = true;
}
};
const scrollToTop = (event) => {
event.preventDefault();
window.scrollTo({
top: 0,
behavior: 'smooth'
});
};
window.addEventListener('scroll', handleScroll);
backToTopBtn.addEventListener('click', scrollToTop);
toggleButtonVisibility();
});
})();</script></body></html>