博客系统更新日志
v0.9.1-TESTA1 - 最大、最重要、最高可用的更新
新增功能
1. 设置面板重构
-
音乐选项卡
- 新增”音乐”选项卡,支持自定义音乐播放列表
- 可添加、删除、排序歌曲
- 支持实时预览和保存
-
导航栏管理优化
- 导航栏选项名称与实际路由匹配(文章集、展板等)
- 支持实时显示/隐藏导航链接,无需刷新(因 人 而 异)
-
点击外部关闭优化
- 采用与主题色面板一致的关闭机制
- 点设置面板外任何位置即可关闭
- 支持 ESC 键关闭
2. 音乐播放器
-
自定义播放列表
- 通过设置面板添加自定义歌曲
- 支持歌曲名称、艺术家、音频链接
- 播放列表保存在 localStorage
- 修改后立即生效
-
滚动条美化
- 播放列表滚动条:5px 宽度,透明轨道
- 悬停时变为主题色
- 支持 Chrome/Safari/Edge 和 Firefox
-
默认播放列表
- 使用 SoundHelix 提供的免费示例音乐
- 可通过设置面板完全自定义
3. 友链页面扩展
-
新增外站推荐部分
- 在友链页面添加”外站推荐”区域
- 支持分类管理外部站点
- 独立的统计卡片显示外站数量
- 使用相同的卡片样式保持一致性
-
导航栏名称更新
- “友链” 改为 “友链&外站”
4. 文章页面优化
- 移除聚光灯模式按钮
- 人性化
- 聚光灯和激光笔功能
- 字体字号随心用
- 无障碍体验
- 支持AI总结(深度思考32B模型)
技术改进
设置面板架构
- 使用
float-panel类实现统一的面板行为 - 通过
setClickOutsideToClose函数处理外部点击 - 使用
float-panel-closed类控制显示/隐藏
导航栏动态控制
// 实时应用导航栏设置function applyNavbarSettings() { const settings = JSON.parse(localStorage.getItem('effectsSettings')); // 根据设置显示/隐藏导航链接 links.forEach(link => { link.style.display = settings.navbarLinks[key] ? '' : 'none'; });}滚动条样式适应(谁知道呢)
/* Webkit 浏览器 */.playlist-items::-webkit-scrollbar { width: 5px;}.playlist-items::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.15); border-radius: 2.5px;}
/* Firefox */.playlist-items { scrollbar-width: thin; scrollbar-color: rgba(0, 0, 0, 0.15) transparent;}配置文件更新
friends.ts
// 外站链接配置export const externalSites: { name: string; desc: string; avatar: string; url: string; category?: string;}[] = [ // 外站链接列表];link-presets.ts
[LinkPreset.friend]: { name: "友链&外站", url: "/friends/",}用户体验改进
-
操作反馈
- 设置修改后立即生效
- 无需刷新页面即可看到变化
-
界面一致性
- 所有面板使用统一的打开/关闭机制
- 滚动条样式统一美化
- 保持与整体设计风格一致
-
数据持久化
- 音乐播放列表保存在 localStorage
- 导航栏设置保存在 localStorage
- 跨会话保持用户配置
阅读功能大升级
新增功能
选项卡式界面设计
- 将功能分为两个选项卡,界面更清晰
- 阅读设置选项卡:字体大小、行距、无障碍功能
- 辅助工具选项卡:聚光灯、激光笔等演示工具
- 选项卡切换流畅,带动画效果
1. 聚光灯模式
- 跟随鼠标的聚光灯效果,帮助专注阅读
- 快捷键:
Ctrl+Shift+S - 设置自动保存到 localStorage
2. 激光笔功能
- 鼠标位置显示红色发光点
- 适合在线演示和教学
- 快捷键:
Ctrl+Shift+L - 可与聚光灯同时使用
3. 无障碍阅读功能
易读模式
- 增加字间距(letter-spacing: 0.05em)
- 增加词间距(word-spacing: 0.1em)
- 增大段落和标题间距
- 特别适合阅读障碍用户
高对比度模式
- 全局对比度增强 20%
- 文本颜色强化
- 自动适配深色/浅色主题
- 帮助视力较弱的用户
专注模式
- 非悬停段落透明度降低至 40%
- 鼠标悬停段落完全显示
- 标题始终完全显示
- 平滑过渡动画
技术实现
聚光灯实现
// 使用 radial-gradient 创建聚光灯效果background: radial-gradient( circle ${radius}px at ${x}px ${y}px, transparent 0%, rgba(0, 0, 0, 0.85) 100%);激光笔实现
// 使用 fixed 定位 + 发光效果box-shadow: 0 0 20px rgba(255, 0, 0, 0.8), 0 0 40px rgba(255, 0, 0, 0.4);无障碍模式
/* 易读模式 */.accessibility-mode { letter-spacing: 0.05em; word-spacing: 0.1em;}
/* 高对比度 */.high-contrast-mode { filter: contrast(1.2);}
/* 专注模式 */.focus-mode p { opacity: 0.4; transition: opacity 0.3s ease;}.focus-mode p:hover { opacity: 1;}用户体验优化
- 设置持久化:所有设置自动保存到 localStorage
- 快捷键支持:提供键盘快捷键,提高效率
- 不影响交互:聚光灯和激光笔使用
pointer-events: none - 性能优化:使用 CSS transform,性能优异
- 响应式设计:适配各种屏幕尺寸
浏览器兼容性
- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
模态框突破父容器限制
更新
本次更新对博客系统进行了全面的用户体验优化,重点解决了模态框组件被父容器限制的技术难题,并添加了多项实用功能。
问题
在 Web 开发中,模态框(Modal)组件经常会遇到一个棘手的问题:父容器的 CSS 属性限制。
当父容器设置了以下属性时,子元素的 position: fixed 会失效:
transformperspectivefilterbackdrop-filterwill-changecontain
在我们的博客系统中,文章内容区域(.markdown-content)使用了多种 CSS 效果,导致模态框无法正确定位到屏幕中央,而是被限制在父容器内部。
传统解决方案的局限
方案一:提升 z-index
.modal { z-index: 99999 !important;}问题:只能解决层级问题,无法解决定位问题。
方案二:使用 Portal(React)
ReactDOM.createPortal(modal, document.body)问题:Svelte 没有内置的 Portal API。
方案三:调整父容器样式
.parent { transform: none !important;}问题:会破坏现有的视觉效果。
我们的解决方案:Svelte 响应式 + DOM 操作
经过多次尝试,得出一个完美的解决方案:利用 Svelte 的响应式系统,在运行时将模态框元素移动到 document.body。
核心代码实现
<script lang="ts"> import { onMount, onDestroy } from 'svelte';
export let show = false; let modalElement: HTMLDivElement;
// 响应式 $: if (show && modalElement) { // 将模态框移动到 body document.body.appendChild(modalElement); document.body.style.overflow = 'hidden'; } else if (!show && typeof document !== 'undefined') { document.body.style.overflow = ''; }
onDestroy(() => { if (typeof document !== 'undefined') { document.body.style.overflow = ''; } });</script>
{#if show} <div bind:this={modalElement} class="modal-root" on:click={close} > <div class="modal-content" on:click|stopPropagation> <!-- 内容 --> </div> </div>{/if}
<style> .modal-root { /* 使用 !important 确保样式不被覆盖 */ position: fixed !important; top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important; width: 100vw !important; height: 100vh !important; z-index: 999999 !important;
/* 背景和模糊 */ background: rgba(0, 0, 0, 0.6) !important; backdrop-filter: blur(12px) !important; -webkit-backdrop-filter: blur(12px) !important;
/* 居中布局 */ display: flex !important; align-items: center !important; justify-content: center !important; }</style>技术要点解析
1. Svelte 响应式语句 $:
$: if (show && modalElement) { document.body.appendChild(modalElement);}这是 Svelte 的响应式语法,当 show 或 modalElement 变化时自动执行。这样我们可以在模态框显示时,动态地将其移动到 document.body。
2. bind:this 绑定
<div bind:this={modalElement}>获取 DOM 元素的引用,这样我们才能操作它。
3. 事件冒泡控制
<div on:click={close}> <div on:click|stopPropagation>- 外层:点击遮罩关闭
- 内层:
stopPropagation阻止事件冒泡,点击内容不关闭
4. 使用 !important 强制样式
由于元素会被移动到 body,可能受到全局样式影响,使用 !important 确保样式生效。
5. 滚动锁定
document.body.style.overflow = 'hidden';模态框打开时禁止页面滚动,提升用户体验。 这就是本博客所有文章“分享”逻辑,详见↓
其他重要更新
1. 文章互动功能
收藏功能
function addFavorite() { const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0; const shortcut = isMac ? 'Cmd+D' : 'Ctrl+D'; alert(`请按 ${shortcut} 将本页添加到书签`);}分享模态框 - 飞机票设计
采用机场登机牌的设计风格:
- 渐变色头部
- 虚线分隔
- 圆形镂空效果
- 真实的 CODE128 条码
- 扫描线动画
import JsBarcode from 'jsbarcode';
function generateBarcode() { const barcodeData = `${slug}-${Date.now()}`.substring(0, 20);
JsBarcode(barcodeCanvas, barcodeData, { format: 'CODE128', width: 2, height: 60, displayValue: false, background: 'transparent', lineColor: isDark ? '#ffffff' : '#000000' });}PDF 导出功能
使用浏览器原生打印功能,配合专门的打印样式:
@media print { #navbar, #sidebar, .post-actions { display: none !important; }
.markdown-content { font-size: 12pt !important; line-height: 1.6 !important; }
.markdown-content a[href]:after { content: " (" attr(href) ")"; }}2. 阅读设置
同样使用”逃脱父容器”技术实现:
<div class="settings-root"> <div class="settings-content"> <!-- 字体大小、行距调节 --> </div></div>设置会保存到 localStorage,下次访问自动应用。
3. 时光流逝组件
独立的卡片组件,分钟更新制,显示:
- 今日已过去
- 本周已过去
- 本月已过去
- 今年已过去
4. 评论系统
集成 Giscus,基于 GitHub Discussions:
技术栈
- 框架: Astro + Svelte
- 样式: Tailwind CSS + 自定义 CSS
- 条码生成: JsBarcode
- 二维码生成: qrcode
- 评论系统: Giscus
- 部署: Vercel
性能优化
- 按需加载:使用
client:load指令 - CSS 动画:优先使用 CSS 而非 JavaScript
- 防抖节流:避免频繁的 DOM 操作
- 懒加载:图片和组件按需加载
总结
本次更新的核心是突破父容器限制的技术实现。使得Fuwari的内容不在受限于一个HTML渲染器! 那么,本人的关键词系统将会在后续按照此方法更新!
希望这篇文章能帮助遇到类似问题的开发者!
技术关键词: Svelte, Modal, Portal, CSS Position, DOM Manipulation, Responsive Design
最后更新: 2026-02-11
作者: xhc861