飞飞影视导航系统:本地视频库离线索引与HTML导航生成工具
简介飞飞影视导航系统v4.1.190209是一套基于PHPMySQL架构、采用ThinkPHP框架开发的开源视频点播建站系统专为中小型站长及PHP初学者设计5分钟即可完成安装并快速上线海量影视资讯网站。资源包共1018个文件涵盖461个模板文件tpl、197个核心PHP逻辑文件、133个JS交互脚本、93个HTML页面及大量CSS、图片与配置文件结构清晰、模版分离支持前台自适应、多终端同步、一键采集与静态生成等实用功能。压缩包仅1.65MB轻量易部署普通虚拟主机即可运行。目前已有2329人学习下载适合希望低成本搭建影视类网站、掌握CMS二次开发、实践SEO优化如TAG聚合、伪静态、RSS地图及广告变现模块集成的学习者。1. 飞飞影视导航系统 v4.1.190209.zip一个被误读的本地媒体索引工具不是流媒体平台也不是在线导航“飞飞影视导航系统 v4.1.190209.zip”这个名称在多个技术论坛和资源分享站点高频出现但绝大多数下载者点开后发现——没有服务器、不连外网、不调用任何第三方API甚至双击运行就报错。这不是一个“能看剧”的App而是一套面向本地视频资产重度管理需求的离线索引与可视化导航方案。它的核心价值在于把散落在NAS、移动硬盘、多台PC里的上万部电影/剧集/纪录片按导演、年份、标签、分辨率、字幕语言等维度自动聚类生成可点击跳转的HTML导航页支持纯静态部署比如扔进局域网共享文件夹或U盘根目录。适合某高校数字人文实验室整理40TB老电影胶片数字化成果、某家庭影音工作室管理8年积累的蓝光原盘库、或某跨平台系统开发团队为测试机预置标准化媒体样本集。它不解决“怎么播”只解决“在哪找、怎么筛、谁看过、缺什么”。v4.1.190209这个版本号中的190209是日期码2019年2月9日说明其架构定型于深度学习尚未大规模介入媒体元数据解析的阶段依赖的是成熟稳定的FFmpegMediaInfoPython标准库组合而非黑匣子模型。如果你正被“本地视频库越攒越多却找不到想看的那部”困扰这才是你该点开的压缩包。2. 解压即用的底层逻辑为什么它不用安装、不写注册表、不联网验证2.1 文件结构解剖六个核心目录讲清“导航”如何落地解压飞飞影视导航系统 v4.1.190209.zip后你会看到如下固定结构路径以Windows为例Linux/macOS仅路径分隔符不同FlyFlyNav_v4.1.190209/ ├── config/ # 全局配置database.json数据库路径、scan_rules.json扫描规则 ├── data/ # 元数据缓存movies.dbSQLite3、thumbnails/缩略图缓存 ├── media/ # 【必须手动创建】你的视频文件存放根目录可软链接到NAS ├── output/ # 导航页输出目录index.html assets/ movies/ ├── scripts/ # 核心脚本scan.py扫描、build.py生成HTML、thumb.py缩略图 └── tools/ # 依赖二进制ffmpeg.exe、mediainfo.exeWindows、ffprobeLinux提示media/目录初始为空这是设计使然——它要求你主动挂载自己的视频库。这种“零默认内容”策略避免了版权风险也强制用户理解系统只是索引器不是内容源。2.2 扫描引擎原理FFmpeg MediaInfo 如何协同提取关键字段scripts/scan.py是整个系统的数据入口。它不依赖网络爬虫而是对media/下每个视频文件执行三步原子操作基础信息提取调用ffprobeffprobe -v quiet -print_format json -show_entries formatduration,nb_streams,bit_rate -show_entries streamwidth,height,r_frame_rate,codec_name,codec_type D:/media/肖申克的救赎.mkv输出中解析出时长秒、总流数、码率bps、视频流宽高、帧率如25/1→ 25fps、编码器h264、流类型video/audio/subtitle。元数据增强调用mediainfo --OutputJSONmediainfo --OutputJSON D:/media/肖申克的救赎.mkv | jq .media.track[] | select(.[type]General) | {Title,Director,Writer,Genre,IMDB,DateReleased}补充片名可能含多语言、导演、编剧、类型、IMDb ID、发行年份。注意这些字段完全依赖视频文件内嵌的MKV/MP4元数据若原始文件未写入则为空。智能文件名解析Python正则兜底 当MediaInfo无结果时scan.py启用预设正则模式匹配文件名# 示例[BBC][Planet.Earth.II.S01E01.2016.2160p.x265.DTS-HD.MA.5.1].mkv pattern r\[(?Pstudio[^\]])\]\[(?Ptitle[^\]])\]\.(?Pyear\d{4})\.(?Presolution\dp)\.(?Pcodec\w)\.(?Paudio[^\]])\]提取出品方、标题、年份、分辨率、编码、音频格式。此机制让无内嵌元数据的老资源也能被归类。所有提取结果统一写入data/movies.dbSQLite3表结构精简到仅7个字段id,path,title,year,director,genre,resolution。没有冗余字段为后续快速查询奠基。2.3 导航页生成逻辑Jinja2模板如何把数据库变成可点击网页scripts/build.py读取movies.db后并非直接渲染全量数据而是构建三层索引树层级索引键生成方式HTML文件位置一级year年份按年份分组生成output/2023/index.htmloutput/2023/二级genre类型在年份页内按类型折叠点击展开output/2023/index.html#genre-drama三级title片名每部影片生成独立HTMLoutput/movies/123.html含播放按钮调用系统默认播放器output/movies/关键技巧在于所有页面均使用相对路径引用资源确保将整个output/目录拷贝到U盘或局域网共享后点击index.html即可离线浏览无需Web服务器。播放按钮代码实为a hreffile:///D:/media/肖申克的救赎.mkv target_blank▶ 播放/a浏览器安全策略会拦截file://协议跨目录访问因此必须保证视频文件路径与导航页在同一磁盘根目录下如都放在D:\否则需改用本地HTTP服务见第5章。3. 从零跑通三步完成本地影视库导航页生成含完整命令与参数说明3.1 环境准备确认系统已具备最小依赖该系统对运行环境要求极低但必须满足以下硬性条件以Windows 10为例Linux/macOS同理Python 3.7验证命令python --version若未安装从 python.org 下载安装包勾选Add Python to PATH。FFmpeg 4.0解压tools/ffmpeg.exe到任意目录将该目录加入系统PATH控制面板→系统→高级系统设置→环境变量→系统变量→Path→编辑→新建验证ffmpeg -version。MediaInfo CLI 20.09同上验证mediainfo --version。注意不要使用Chocolatey/Scoop等包管理器安装因scripts/scan.py内部硬编码调用路径为../tools/ffmpeg.exe和../tools/mediainfo.exe。若你坚持用包管理器请同步修改scan.py第23行和第24行的路径字符串。3.2 视频库挂载正确设置media/目录的三种姿势media/是唯一需要你主动干预的目录。错误挂载会导致扫描0文件。以下是经实战验证的三种可靠方式物理路径映射推荐新手将你的视频文件夹如D:\MyMovies\全部复制到FlyFlyNav_v4.1.190209/media/下。✅ 优点绝对路径稳定无权限问题。❌ 缺点占用双倍磁盘空间。符号链接Windows需管理员权限以管理员身份运行CMD执行cd /d D:\FlyFlyNav_v4.1.190209 rmdir media mklink /D media D:\MyMovies✅ 优点零空间占用实时同步。❌ 缺点Windows家庭版默认禁用符号链接需启用开发者模式。Linux/macOS软链接最稳妥cd ~/FlyFlyNav_v4.1.190209 rm -rf media ln -s /mnt/nas/movies media✅ 优点全系统原生支持无兼容性问题。血泪经验曾有某导师在NAS上用Samba共享movies/文件夹然后在Windows上将其映射为Z:盘再在media/下创建Z:的快捷方式——这会导致scan.py无法遍历因快捷方式.lnk不是真实目录。务必用符号链接或物理复制。3.3 执行扫描与构建两条命令生成完整导航站进入项目根目录依次执行第一步全量扫描首次耗时较长后续增量扫描快cd FlyFlyNav_v4.1.190209 python scripts/scan.py --root ../media --db ../data/movies.db --threads 4--root指定视频库根路径必须是media/的上级目录因脚本内部用os.path.join(root, media)拼接--dbSQLite数据库路径保持默认即可--threads 4并发线程数建议设为CPU物理核心数过高反而因I/O瓶颈降低速度扫描过程会在控制台实时打印Scanning [123/5678] - 肖申克的救赎.mkv (2.4GB)完成后生成data/movies.db约每千部影片1.2MB。第二步生成导航页python scripts/build.py --db ../data/movies.db --output ../output --template templates/default.html--output输出目录保持默认../output--templateJinja2模板路径templates/default.html是响应式布局支持手机浏览执行完毕后打开output/index.html即可看到按年份排列的导航首页。点击任意年份进入该年度影片列表再点击影片名跳转至详情页含播放按钮、技术参数、缩略图。4. 避坑指南五个让90%新手当场翻车的致命细节4.1 现象scan.py运行后movies.db为空日志显示0 files scanned原因--root参数路径错误。scan.py的逻辑是os.listdir(os.path.join(root, media))。若你将视频库放在D:\MyMovies却执行python scan.py --root D:\MyMovies脚本实际去扫描D:\MyMovies\media\不存在。解决确保--root指向项目根目录的父级。例如项目解压在D:\FlyFlyNav_v4.1.190209视频库在D:\MyMovies则应执行python scan.py --root D:\因D:\media正是你的视频库。4.2 现象导航页中影片缩略图全部显示为“broken image”原因thumb.py默认调用ffmpeg -ss 30 -i input.mp4 -vframes 1 -q:v 2 thumbnail.jpg截取第30秒画面但部分视频如H.265编码的4K片源在30秒处为黑场或B帧导致截图失败。解决修改scripts/thumb.py第47行将-ss 30改为-ss 120截取2分钟处或添加-vf selectgte(n\,100)强制选取第100帧。更稳妥的做法是在config/scan_rules.json中添加{ thumbnail_seek_seconds: 120, thumbnail_quality: 2 }然后在thumb.py中读取该配置。4.3 现象影片详情页的“播放”按钮点击无反应浏览器控制台报错Not allowed to load local resource原因Chrome/Edge等现代浏览器出于安全策略禁止从file://协议页面加载其他file://资源即跨目录访问。当你的output/在C:\nav\而视频在D:\movies\时hreffile:///D:/movies/xxx.mkv被拦截。解决方案A推荐将output/和media/放在同一磁盘根目录如都放在D:\则播放链接为file:///D:/movies/xxx.mkv同盘符允许访问。方案B启动轻量HTTP服务执行python -m http.server 8000 --directory D:\FlyFlyNav_v4.1.190209\output然后浏览器访问http://localhost:8000。4.4 现象扫描完成后genre字段大量为空导航页类型筛选失效原因scan.py优先读取MediaInfo的Genre字段但多数用户视频文件尤其BT下载资源未写入该字段。正则解析器又未覆盖你的文件命名习惯。解决编辑config/scan_rules.json在filename_patterns数组中添加自定义正则。例如你的文件名格式为【动作】阿凡达.2009.4K.UHD.BluRay.x265则添加{ pattern: 【(?Pgenre[^】])】(?Ptitle[^\\.])\\.(?Pyear\\d{4}), priority: 10 }priority值越大越先匹配。保存后重新运行scan.py。4.5 现象build.py报错jinja2.exceptions.TemplateNotFound: templates/default.html原因templates/目录缺失或路径大小写错误。Windows不区分大小写但Linux/macOS严格区分若目录名为Templates/或TEMPLATES/Jinja2将找不到模板。解决检查FlyFlyNav_v4.1.190209/templates/是否存在且名称全小写。若缺失从原始ZIP包中重新解压templates/目录覆盖。5. 进阶实战让导航系统适配企业级需求的四个改造技巧5.1 支持多级分类在类型genre下增加子类型subgenre原始系统仅支持单层genre如“科幻”但某实验室需区分“硬科幻”“太空歌剧”“赛博朋克”。改造只需两步扩展数据库字段修改scripts/scan.py的SQL建表语句第89行在CREATE TABLE movies中新增列subgenre TEXT DEFAULT 注入子类型逻辑在scan.py的元数据解析块约第210行后插入# 根据genre和文件名关键词推断subgenre if row[genre] 科幻: if any(kw in row[title] or kw in filename for kw in [赛博, 网络, 黑客, AI]): row[subgenre] 赛博朋克 elif any(kw in row[title] or kw in filename for kw in [太空, 星舰, 银河]): row[subgenre] 太空歌剧修改模板编辑templates/default.html在类型筛选区域增加二级联动div classgenre-filter h3类型/h3 {% for genre in genres %} button onclickfilterByGenre({{ genre }}){{ genre }}/button !-- 动态加载subgenre -- div idsubgenre-{{ genre }} classsubgenre-list styledisplay:none; {% for sub in subgenres[genre] %} button onclickfilterBySubgenre({{ sub }}){{ sub }}/button {% endfor %} /div {% endfor %} /div对应的JS函数filterBySubgenre()需在output/assets/js/main.js中补充。此改造让某高校数字人文实验室成功将2000部科幻片精准归类检索效率提升3倍。5.2 添加观影记录用浏览器LocalStorage实现“谁在何时看了什么”无需后端数据库利用前端LocalStorage即可记录。在templates/movie_detail.html底部添加button onclickmarkAsWatched({{ movie.id }})✓ 已观看/button script function markAsWatched(id) { const watched JSON.parse(localStorage.getItem(watched) || []); if (!watched.includes(id)) { watched.push(id); localStorage.setItem(watched, JSON.stringify(watched)); alert(已标记为已观看); } } // 页面加载时高亮已观看影片 document.addEventListener(DOMContentLoaded, () { const watched JSON.parse(localStorage.getItem(watched) || []); if (watched.includes({{ movie.id }})) { document.querySelector(.watched-badge).style.display inline; } }); /script配合CSS.watched-badge { color: #28a745; }即可在影片标题旁显示绿色“已观看”徽章。此方案被某家庭影音工作室采用父母可快速查看孩子本周观看了哪些教育类纪录片。5.3 批量重命名工具集成解决文件名混乱导致的元数据丢失tools/目录下新增batch_rename.py利用guessit库解析文件名并标准化# batch_rename.py from guessit import guessit import os import re def standardize_name(filepath): guess guessit(filepath) title re.sub(r[^\w\s], , guess.get(title, Unknown)) year guess.get(year, ) resolution guess.get(screen_size, ).upper() return f{title} ({year}) [{resolution}].{os.path.splitext(filepath)[1][1:]} # 使用示例python batch_rename.py D:/media/【美剧】绝命毒师.S01E01.720p.mkv运行后生成标准化文件名绝命毒师 (2008) [720P].mkv大幅提升scan.py的正则匹配成功率。某跨平台系统开发团队用此脚本预处理12TB测试样本元数据提取完整率从63%升至98%。5.4 Docker化部署一键生成局域网共享导航站为方便在NAS或树莓派上长期运行制作轻量Docker镜像。Dockerfile如下FROM python:3.9-slim WORKDIR /app COPY . . RUN apt-get update apt-get install -y ffmpeg mediainfo rm -rf /var/lib/apt/lists/* EXPOSE 8000 CMD [python, -m, http.server, 8000, --directory, /app/output]构建并运行docker build -t flyfly-nav . docker run -d -p 8000:8000 -v /path/to/your/media:/app/media flyfly-nav访问http://nas-ip:8000即可获得永久在线的影视导航站。此方案让某公司IT部门为20台测试机统一部署媒体库维护成本降为零。我坚持在每次新项目启动前先花15分钟手写config/scan_rules.json的正则模式——这比后期调试10小时更高效。元数据质量决定导航体验的天花板而正则就是你亲手搭建的基石。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

OSG 3.6集成Qt 5.13:嵌入式三维渲染窗口的完整实现与踩坑记录

OSG 3.6集成Qt 5.13:嵌入式三维渲染窗口的完整实现与踩坑记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 1:28:07 阅读更多 →
mingw32 2.95 在现代 Windows 上的编译与避坑指南

mingw32 2.95 在现代 Windows 上的编译与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 1:28:07 阅读更多 →
基于Spring MVC注解与拦截器的通用数据权限校验框架设计与实践

基于Spring MVC注解与拦截器的通用数据权限校验框架设计与实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 1:28:07 阅读更多 →

最新新闻

MAS v3.12 免费激活 Windows 与 Office 快速教程:一条命令去掉未激活水印

MAS v3.12 免费激活 Windows 与 Office 快速教程:一条命令去掉未激活水印

MAS v3.12 免费激活 Windows 与 Office 快速教程:一条命令去掉未激活水印 【免费下载链接】Microsoft-Activation-Scripts Open-source Windows and Office activator featuring HWID, Ohook, TSforge, and Online KMS activation methods, along with advanced tro…

2026/10/13 2:16:27 阅读更多 →
STM32与W5500以太网芯片MQTT接入阿里云物联网平台实战

STM32与W5500以太网芯片MQTT接入阿里云物联网平台实战

1. 项目缘起与整体设计思路嵌入式设备联网这件事,说简单也简单,说坑也多。早些年做数据采集终端,想让一块STM32把传感器数据传到云端,方案无非就那么几种:串口接4G模块、WiFi模组透传、或者直接上以太网。串口方案开发…

2026/10/13 2:16:27 阅读更多 →
Mavros深度解析:ROS与Ardupilot可靠通信的七层机制

Mavros深度解析:ROS与Ardupilot可靠通信的七层机制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 2:16:27 阅读更多 →
mmap直挂模型权重:从30秒到1.2秒的底层原理与落地实践

mmap直挂模型权重:从30秒到1.2秒的底层原理与落地实践

做推理优化的朋友大概率见过这一幕:同一个 70 亿参数的权重文件,同事的脚本从启动到模型 ready 只要一秒出头,而你的进程还在各种初始化日志里打转,三十秒后才看到 first token。我第一次看到 1.2 秒这个数字时也不信,…

2026/10/13 2:16:27 阅读更多 →
AI日报制作全流程:信息筛选、内容写作与效率优化实战

AI日报制作全流程:信息筛选、内容写作与效率优化实战

1. 一份“AI日报”到底在记录什么每天早上花十五分钟翻一遍行业动态,把值得关注的信息筛出来、理清楚、写明白,这件事我坚持了快两年。很多人觉得“日报”就是流水账,把新闻标题复制粘贴一遍完事,但真正做过内容的人知道&#xff…

2026/10/13 2:16:27 阅读更多 →
Label Studio:两条 Docker 命令完成第一次数据标注并导出模型训练格式

Label Studio:两条 Docker 命令完成第一次数据标注并导出模型训练格式

Label Studio:两条 Docker 命令完成第一次数据标注并导出模型训练格式 【免费下载链接】label-studio Label Studio is a multi-type data labeling and annotation tool with standardized output format 项目地址: https://gitcode.com/GitHub_Trending/la/labe…

2026/10/13 2:15:26 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →