前言
看了小鱼三周年的博客装修,对这个桌面图标和弹窗样式一见钟情!一开始只是想复刻其中一个挂件功能,结果不知不觉就走向了一个又一个样式换新的无底洞……最终成果如下!个人很喜欢这种报错类(?)的游戏风格设计——
感谢装修过程中鱼师傅倾囊相授,狠狠复制了不少现成代码秘籍,ChatGPT我现在有新的老公了你就安心地去吧!
参考窗口样式
horrorchic↗
aeon-flexx-dead-girl↗
statuscafe挂件弹窗
参考了Creating a Feed Reader from StatusCafe教程,首先status cafe论坛注册一个账号,审核一般需要两到三天,我是等了两天收到了管理员的邀请邮件。
然后我们就可以来新建第一个窗口啦!在/layouts/partials
目录下新建cafe.html
。这个文件最后会在’/layouts/_default/baseof.html’下渲染。
<!-- RSS Feed 窗口 -->
<div class="window" id="feed-window">
<div class="window-header">
<div style="display: inline-block;">通信完成</div>
<button class="close-btn" onclick="closeWindow('feed-window')">
<img src="https://img.naturaleki.one/lock/closebtn.png" />
</button>
</div>
<div class="scrollable-content" id="feed-reader"></div>
</div>
然后在下方唰地创建一个<script></script>
,写入js代码。此代码的作用是将 feed 转换为 XML,从而提取 feed 的数据,具体一些详细的自定义可以看原教程,我让ChatGPT把时间显示改为了长毛象的样式(?
// 获取并展示RSS数据
const feedURL = 'https://status.cafe/users/pokalo.atom';
fetch(feedURL)
.then(response => response.text())
.then(str => {
const parser = new window.DOMParser();
const data = parser.parseFromString(str, "text/xml");
const entries = data.querySelectorAll("entry");
let html = ``;
// 时间格式化函数
function timeAgo(publishedDate) {
const now = new Date();
const published = new Date(publishedDate);
const diffInSeconds = Math.floor((now - published) / 1000);
const secondsInMinute = 60;
const secondsInHour = 60 * secondsInMinute;
const secondsInDay = 24 * secondsInHour;
if (diffInSeconds < secondsInMinute) {
return `${diffInSeconds} seconds ago`;
} else if (diffInSeconds < secondsInHour) {
const minutes = Math.floor(diffInSeconds / secondsInMinute);
return `${minutes} minute${minutes > 1 ? 's' : ''} ago`;
} else if (diffInSeconds < secondsInDay) {
const hours = Math.floor(diffInSeconds / secondsInHour);
return `${hours} hour${hours > 1 ? 's' : ''} ago`;
} else {
const days = Math.floor(diffInSeconds / secondsInDay);
return `${days} day${days > 1 ? 's' : ''} ago`;
}
}
// 限制为最多显示 15 条条目
for (let i = 0; i < Math.min(entries.length, 15); i++) {
const el = entries[i];
const title = el.querySelector("title").innerHTML.slice(0, 9).trim();
const content = el.querySelector("content").textContent.trim();
const publishedDate = el.querySelector("published").innerHTML;
const timeAgoText = timeAgo(publishedDate);
html += `
<div class="feed-item">
<p>${title} - ${timeAgoText}</p>
<p>${content}</p>
</div>
`;
}
html += `<p style="text-align: center;"><a href="https://status.cafe/users/pokalo" target="_blank">前往更深处</a></p>`;
document.getElementById("feed-reader").innerHTML = html;
})
.catch(error => {
console.error('Error fetching or parsing data:', error);
});
打开和关闭窗口的js代码,隐藏菜单是为了适配fuji主题的手机端菜单唤起,可以直接忽略。
// 打开窗口
function openWindow(windowId) {
const window = document.getElementById(windowId);
if (window) {
window.style.display = 'block'; // 显示指定的窗口
}
// 隐藏菜单
const menu = document.querySelector('.sidebar-mobile');
if (menu) {
menu.style.display = 'none'; // 隐藏菜单
}
}
// 关闭窗口
function closeWindow(windowId) {
const window = document.getElementById(windowId);
if (window) {
window.style.display = 'none';
}
}
窗口拖动代码,并在拖动窗口的同时让窗口显示在最上层。
// 拖动窗口功能
function makeWindowDraggable(element) {
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
const windowWidth = element.offsetWidth;
const windowHeight = element.offsetHeight;
// 获取窗口顶部(标题栏)
const header = element.querySelector('.window-header'); // 确保选择正确的标题栏
// 仅在标题栏上启用拖动功能
if (header) {
header.onmousedown = dragMouseDown;
}
function dragMouseDown(e) {
e.preventDefault();
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
document.onmousemove = elementDrag;
bringToFront(element); // 点击时提升到最上层
}
function elementDrag(e) {
e.preventDefault();
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
let newTop = element.offsetTop - pos2;
let newLeft = element.offsetLeft - pos1;
// 使窗口不被拖出屏幕范围
newTop = Math.max(0, Math.min(newTop, window.innerHeight - windowHeight));
newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - windowWidth));
element.style.top = newTop + "px";
element.style.left = newLeft + "px";
}
function closeDragElement() {
document.onmouseup = null;
document.onmousemove = null;
}
function bringToFront(element) {
const allWindows = document.querySelectorAll('.window');
allWindows.forEach(window => window.style.zIndex = 0); // Reset z-index
element.style.zIndex = 1000; // Bring the dragged window to the front
}
}
document.querySelectorAll('.window').forEach(windowElement => {
makeWindowDraggable(windowElement);
});
然后是css设置,因为js代码中用于定向的class类名都是相同的,所以不同功能窗口样式的自定义以id区分。
#feed-window.window {
width: 25%;
max-width: 480px;
height: 50%;
top: 20%;
left: 10%;
}
.window {
position: fixed;
background-color: var(--color-bg);
border-radius: 3px;
padding: 0; /* 去除内边距 */
display: none;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); /* 更加明显的阴影 */
border: 2px solid var(--color-primary);
box-sizing: border-box; /* 确保边框不影响内部布局 */
overflow: hidden; /* 防止内容溢出 */
}
.window-header {
background-color: var(--color-bg);
padding: 8px 15px; /* 内边距调整 */
color: var(--color-primary);
font-family: "ipx";
border-bottom: 2px solid var(--color-primary); /* 分割线 */
display: flex;
align-items: center; /* 垂直居中 */
justify-content: space-between; /* 标题和按钮两侧对齐 */
font-size: 22px; /* 调整标题文字大小 */
}
.window-header div {
flex-grow: 1; /* 标题区域占据剩余空间 */
font-weight: bold; /* 突出标题 */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis; /* 如果标题过长,显示省略号 */
}
/* 关闭按钮样式 */
.close-btn {
position: absolute;
right: 10px;
border: 2px solid var(--color-primary);
border-radius: 2px;
width: 35px;
height: 35px;
cursor: pointer;
}
.close-btn img {
position: absolute;
top: 50%;
left: 50%;
width: 30px;
height: 30px;
background-color: var(--color-bg);
transform: translate(-50%, -50%);
}
/* 滚动区域样式 */
.scrollable-content {
max-height: calc(100% - 60px); /* 增加顶部空间 */
overflow-y: auto; /* 垂直滚动条 */
padding-right: 15px;
padding-top: 20px; /* 增加顶部内边距,避免靠近标题 */
padding-left: 15px;
padding-bottom: 10px;
}
/* 通用滚动条样式 */
.scrollable-content {
scrollbar-color: #8aa2d3 #f6f8fa; /* 滑块颜色 | 轨道颜色 */
}
.scrollable-content::-webkit-scrollbar {
width: 10px; /* 滚动条宽度 */
height: 8px; /* 横向滚动条高度 */
}
.scrollable-content::-webkit-scrollbar-track {
background: #f6f8fa; /* 滚动条轨道背景色 */
}
.scrollable-content::-webkit-scrollbar-thumb {
background: #8aa2d3; /* 滚动条滑块颜色 */
}
/* 滚动条按钮:上下箭头 */
.scrollable-content::-webkit-scrollbar-button {
background: #f6f8fa; /* 按钮背景色 */
border: none; /* 去除边框 */
height: 12px; /* 按钮高度 */
width: 12px; /* 按钮宽度 */
display: flex;
justify-content: center;
align-items: center;
}
/* 上箭头 */
.scrollable-content::-webkit-scrollbar-button:single-button:decrement {
background-image: url('data:image/svg+xml;charset=UTF-8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24"%3E%3Cpath fill="%238aa2d3" d="M12 6l8 8H4z"/%3E%3C/svg%3E');
background-repeat: no-repeat;
background-position: center;
}
/* 下箭头 */
.scrollable-content::-webkit-scrollbar-button:single-button:increment {
background-image: url('data:image/svg+xml;charset=UTF-8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24"%3E%3Cpath fill="%238aa2d3" d="M12 18l8-8H4z"/%3E%3C/svg%3E');
background-repeat: no-repeat;
background-position: center;
}
.feed-item {
border: 1px solid var(--color-font);
padding: 10px;
margin-bottom: 10px;
background-color: var(--color-codebg);
font-size: 16px; /* 修改文字大小 */
}
这样的话,弹窗部分就完工了,接着我们需要现捏出一个开关来测试一下。
<a href="javascript:void(0);" onclick="openWindow('feed-window')">开关</a>
点击开关就可以唤起cafe挂件了!之前其实是想把窗口做成类似win95的样式,不过我的设计能力拼尽全力也只能做到这样的程度了,自己看得舒服就行!顺带一提这个类说说的窗口名daybit来源是我新晋五个月(?)的家妻…………
做完这个后UI设计略逊百筹的artitalk就被我快乐地删除了。
搜索弹窗
最初只是想抄完cafe挂件就收工,结果在欣赏窗口地过程中意外发现了之前装得累死累活的pjax插件给我带来的小惊喜:博客页面切换时,弹窗并不会消失,并且只要不刷新,关闭后切换页面也会记忆拖动位置和输入内容。于是一个大胆的装修计划逐渐在我脑内成形,考完期末后立刻着手实践,第一步先从搜索开始。代码就继续写在cafe.html
里面了。
<!-- 搜索窗口 -->
<div class="window" id="search-window">
<div class="window-header">
<div style="display: inline-block;">小狗搜索员为您服务!</div>
<button class="close-btn" onclick="closeWindow('search-window')">
<img src="https://img.naturaleki.one/lock/closebtn.png" />
</button>
</div>
<link href="/css/pagefind-ui.css" rel="stylesheet">
<script src="/search/pagefind-ui.js" type="text/javascript"></script>
<div class="scrollable-content" id="search"></div>
<script>
// 初始化 Pagefind 搜索
window.addEventListener('DOMContentLoaded', (event) => {
// 初始化 PagefindUI
const pagefindUI = new PagefindUI({
element: "#search",
showImages: false,
excerptLength: 20,
translations: {
placeholder: "请小狗搜索员搜索——",
clear_search: "删除!",
load_more: "让小狗搜索员继续寻找",
search_label: "站内检索",
filters_label: "文件分类",
zero_results: "小狗搜索员没有找到关于 [SEARCH_TERM] 的文件,可能一不小心被丢到地狱去了……",
many_results: "小狗搜索员成功找到了 [COUNT] 个关于 [SEARCH_TERM] 的文件!",
one_result: "小狗搜索员成功找到了 [COUNT] 个关于 [SEARCH_TERM] 的文件!",
alt_search: "小狗搜索员找不到关于 [SEARCH_TERM] 的文件。但是为你带来了另一份关于 [DIFFERENT_TERM] 的文件!",
search_suggestion: "小狗搜索员没能找到关于 [SEARCH_TERM] 的文件。可以试试以下方案。",
searching: "小狗搜索员正抱着 [SEARCH_TERM] 的委托努力搜索…"
}
});
// 添加事件监听器,处理搜索结果链接的点击事件
const searchContainer = document.querySelector("#search");
searchContainer.addEventListener('click', (event) => {
const target = event.target;
// 确认点击了 A 标签链接
if (target.tagName === 'A') {
event.preventDefault(); // 阻止默认跳转行为
const href = target.getAttribute('href');
// 使用 PJAX 加载新页面
if (window.pjax) {
pjax.loadUrl(href);
} else {
console.warn("PJAX 未初始化,请检查代码。");
// 可选:使用普通跳转作为后备方案
window.location.href = href;
}
}
});
});
</script>
</div>
自定义css。
#search-window.window {
width: 60%;
max-width: 1080px;
height: 55%;
top: 20%;
left: 20%;
transform: translateY(0);
}
然后重新设置一下搜索结果链接pjax跳转的js。
$(document).on('click', 'a.name', function(e) {
e.preventDefault(); // 阻止默认行为
var url = $(this).attr('href'); // 获取链接地址
$.pjax({ url: url, container: '#main' }); // 使用 PJAX 加载内容
});
说起pagefind脚本更新后中文搜索功能更加模糊了,有时需要善用分词搜索才能找到想要的内容,不过对我来说还是挺方便的。
归档弹窗和tag弹窗
直接copy了之前归档样式的html。
<div class="window" id="archives-window">
<div class="window-header">
<div style="display: inline-block;">天堂档案保管室</div>
<button class="close-btn" onclick="closeWindow('archives-window')">
<img src="https://img.naturaleki.one/lock/closebtn.png" />
</button>
</div>
<div class="scrollable-content" id="archives">
<div class="page-info">
<span>{{ i18n "archivesTotalPages" }}{{ len (where .Site.RegularPages "Type" "in" .Site.Params.mainSections) }}</span>
</div>
<div class="empty-space"></div>
<div class="archive">
<div class="archive-year">
<h2><button class="collapsible" onclick="toggleArchive('archive-2025')">2025</button></h2>
<ul id="archive-2025" class="archive-list">
{{ range $index, $page := where .Site.RegularPages "Date.Year" 2025 }}
<li class="archive-item">
<span class="archive-date">{{ $page.Date.Format "01-02" }}</span> <!-- 仅显示月份和日 -->
<a href="{{ $page.Permalink }}" class="archives-link">{{ $page.Title }}</a>
</li>
{{ end }}
</ul>
</div>
</div>
<div class="empty-space"></div>
<div class="archive">
<div class="archive-year">
<h2><button class="collapsible" onclick="toggleArchive('archive-2024')">2024</button></h2>
<ul id="archive-2024" class="archive-list">
{{ range $index, $page := where .Site.RegularPages "Date.Year" 2024 }}
<li class="archive-item">
<span class="archive-date">{{ $page.Date.Format "01-02" }}</span> <!-- 仅显示月份和日 -->
<a href="{{ $page.Permalink }}" class="archives-link">{{ $page.Title }}</a>
</li>
{{ end }}
</ul>
</div>
</div>
<div class="empty-space"></div>
<div class="archive">
<div class="archive-year">
<h2><button class="collapsible" onclick="toggleArchive('archive-2023')">2023</button></h2>
<ul id="archive-2023" class="archive-list">
{{ range $index, $page := where .Site.RegularPages "Date.Year" 2023 }}
<li class="archive-item">
<span class="archive-date">{{ $page.Date.Format "01-02" }}</span> <!-- 仅显示月份和日 -->
<a href="{{ $page.Permalink }}" class="archives-link">{{ $page.Title }}</a>
</li>
{{ end }}
</ul>
</div>
</div>
<div class="empty-space"></div>
<div class="archive">
<div class="archive-year">
<h2><button class="collapsible" onclick="toggleArchive('archive-2022')">2022</button></h2>
<ul id="archive-2022" class="archive-list">
{{ range $index, $page := where .Site.RegularPages "Date.Year" 2022 }}
<li class="archive-item">
<span class="archive-date">{{ $page.Date.Format "01-02" }}</span> <!-- 仅显示月份和日 -->
<a href="{{ $page.Permalink }} " class="archives-link">{{ $page.Title }}</a>
</li>
{{ end }}
</ul>
</div>
</div>
<div class="empty-space"></div>
</div>
</div>
tag按钮样式又这么直接copy了归档年份按钮(?)
<!-- 标签内容跳转窗口 -->
<div class="window" id="tag-window">
<div class="window-header">
<div style="display: inline-block;">文件分类</div>
<button class="close-btn" onclick="closeWindow('tag-window')">
<img src="https://img.naturaleki.one/lock/closebtn.png" />
</button>
</div>
<div class="scrollable-content" id="tags">
<a href="/tags/存活报告" class="tag-btn">存活报告</a>
<a href="/tags/小狗粉刷匠" class="tag-btn">小狗粉刷匠</a>
<a href="/tags/游梦症" class="tag-btn">游梦症</a>
<a href="/tags/数学研究小组" class="tag-btn">数学研究小组</a>
</div>
</div>
二位的css。
/* 归档样式*/
#archives-window.window {
width: 35%;
max-width: 720px;
height: 55%;
top: 20%;
right: 10%;
}
.archive-list {
display: none;
padding: 5px;
list-style-type: none; /* 去掉默认的小圆点 */
}
.archive-item {
padding-left: 12px;
padding-right: 12px;
}
.collapsible {
background-color: #f0f8ff;
color: #8aa2d3;
padding: 10px;
border: 1px solid #8aa2d3;
border-radius: 5px;
outline: none;
}
.collapsible::before {
content: '#';
color: #e6cfe6;
}
/* 按钮悬停时的样式 */
.collapsible:hover {
background-color: #e9f3fb;
}
body[data-theme='dark'] .collapsible {
background-color: #1e1e1e;
}
body[data-theme='dark'] .collapsible::before {
content: '#';
color: #c39bc3;
}
body[data-theme='dark'] .collapsible:hover {
background-color: #272727;
}
/* 标签跳转样式*/
#tag-window.window {
width: 60%;
max-width: 480px;
height: 40%;
top: 30%;
left: 45%;
}
/* 基本按钮样式 */
.tag-btn {
background-color: #f0f8ff;
color: #8aa2d3;
padding: 10px;
border: 1px solid #8aa2d3;
border-radius: 5px;
margin: 4px; /* 增加均匀的外间距 */
display: inline-block; /* 确保按钮大小受内容控制 */
text-align: center; /* 文本居中 */
white-space: nowrap; /* 防止按钮中的文字换行 */
}
/* 前缀符号或图标 */
.tag-btn::before {
content: '#'; /* 你可以替换为你需要的图标 */
color: #e6cfe6;
margin-right: 8px;
}
/* 按钮悬停时的样式 */
.tag-btn:hover {
background-color: #e9f3fb;
}
/* 深色模式下的按钮样式 */
body[data-theme='dark'] .tag-btn {
background-color: #1e1e1e;
}
body[data-theme='dark'] .tag-btn::before {
content: '#'; /* 深色模式下的图标 */
color: #c39bc3;
}
body[data-theme='dark'] .tag-btn:hover {
background-color: #272727;
}
/* 父容器样式 */
#tags.scrollable-content {
display: flex; /* 使用弹性布局 */
flex-wrap: wrap; /* 允许按钮换行 */
gap: 8px; /* 控制按钮之间的间距 */
padding: 10px; /* 确保内容有内边距 */
overflow-x: auto; /* 水平滚动以处理内容溢出 */
}
使用pjax加载归档和tag的链接。
// 检查是否是 <a> 标签,并且是指定的类名
if (target.tagName === 'A' && (target.classList.contains('archives-link') || target.classList.contains('tag-btn'))) {
event.preventDefault(); // 阻止默认跳转
pjax.loadUrl(target.href); // 使用 PJAX 加载链接
}
});
冒险者铭牌(?)弹窗
把之前的游戏记录和长毛象外链整合到了一起,并在左边放了选选老师绘制的美丽年度印象矢量图!
<!-- 礼物窗口 -->
<div class="window" id="gift-window">
<div class="window-header">
<div style="display: inline-block;">莫古力扁扁地走开了库啵</div>
<button class="close-btn" onclick="closeWindow('gift-window')">
<img src="https://img.naturaleki.one/lock/closebtn.png" />
</button>
</div>
<div class="scrollable-content" id="gift">
<div class="gift-card">
<img src="https://img.naturaleki.one/lock/cafe.png" class="left-image" />
<div class="gift-word">
<h3 style="font-family: ipx;color: #8aa2d3;background: rgba(255, 240, 245, 0.4); text-align: center">游戏记录</h3>
<div class="empty-space"></div>
<p>用notion搭建的安利墙</p>
<a href="https://pokalo.notion.site/0cff84da39b14b438b99a1e6bdc83cc1?pvs=4" target="_blank">传送门</a>
<div class="empty-space"></div>
<h3 style="font-family: ipx;color: #8aa2d3;background: rgba(255, 240, 245, 0.4); text-align: center">长毛象</h3>
<div class="empty-space"></div>
<p>毛象个人资料认证用</p>
<p><i class="fa-brands fa-mastodon"></i> :<a rel="me" href="https://wxw.moe/@Delolmo" target="_blank">@[email protected]</a></p>
</div>
</div>
</div>
</div>
css样式。
#gift-window.window {
width: 30%;
max-width: 480px;
height: 45%;
top: 15%;
right: 20%;
}
.gift-card {
background-color: var(--color-codebg);
padding-left: 10px;
padding-right: 10px;
padding-top: 5px;
border: 1px solid var(--color-font);
display: flex; /* 图片和文字并排 */
align-items: center;
}
.left-image {
width: 100px; /* 图片宽度 */
height: auto; /* 按比例调整高度 */
margin-right: 16px; /* 图片和文字的间距 */
object-fit: cover; /* 保持图片比例 */
}
changelog弹窗
在小鱼师傅的急救下学会了直接在弹窗里引入md文件,赞美小鱼!
<div class="window" id="changelog-window">
<div class="window-header">
<div style="display: inline-block;">更新公告</div>
<button class="close-btn" onclick="closeWindow('changelog-window')">
<img src="https://img.naturaleki.one/lock/closebtn.png" />
</button>
</div>
<div class="scrollable-content" id="changelog">
<div class="changelogcontent">
{{ with site.GetPage "changelog" }}
{{ .Content | safeHTML }}
{{ else }}
<p>404 Not Found</p>
{{ end }}
</div>
</div>
</div>
css样式。
.changelogcontent {
padding: 15px;
}
#changelog-window.window {
width: 45%;
max-width: 480px;
height: 60%;
top: 30%;
left: 45%;
}
侧栏导航样式修改
fuji主题的菜单导航有两个,电脑和平板用的是/layouts/partials/sidebar.html
,手机则是/layouts/partials/components.html
,为了达到桌面图标的效果,让ChatGPT把目录前面的元素全部推翻重写了。
像素图标来源streamline和Freepik,后者注册账号后每天可以获得几次免费在线编辑图标的权限。在小鱼博客里看到的pixel safari也特别可爱!但因为风格和博客不太契合所以没有使用。
<style>
/* 图标容器 */
.desktop-icons {
display: flex;
flex-direction: column; /* 保持竖直排列每一行 */
padding: 0;
margin: 0;
list-style: none; /* 去除默认列表样式 */
gap: 5px; /* 每一行之间的间距 */
}
/* 每一行图标 */
.icon-row {
display: flex; /* 每行设置为水平排列 */
justify-content: flex-start; /* 从左开始排列 */
gap: 5px; /* 控制按钮之间的水平间距 */
}
/* 每个图标项 */
.icon-row .desktop-icon {
margin-right: 2px; /* 缩短左右按钮的间距 */
}
.icon-row .desktop-icon:last-child {
margin-right: 0; /* 去除最后一个按钮的额外间距 */
}
/* 图标样式 */
.desktop-icon {
width: 75px;
height: 85px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
cursor: pointer;
}
.desktop-icon:hover {
transform: scale(1.1);
}
.desktop-icon img {
width: 45px;
height: 45px;
margin-bottom: 0;
border-radius: 10px;
border: 2px solid var(--color-primary);
background: var(--color-bg);
padding: 5px;
}
.desktop-icon span {
color: var(--color-primary);
font-size: 12px;
display: block; /* 防止意外偏移 */
text-align: center; /* 居中对齐 */
margin-top: 0; /* 控制上方间距 */
line-height: 1; /* 设置行高来调整文本与图标之间的间距 */
font-family: "ipx en";
}
</style>
<aside class="col-12 col-md-3 float-left sidebar">
<!-- pages -->
<div class="sidebar-item sidebar-pages">
<ul class="desktop-icons">
<!-- 第一行 -->
<div class="icon-row">
<li class="desktop-icon">
<a href="/">
<img src="https://img.naturaleki.one/lock/chruch.png">
<span>Home</span>
</a>
</li>
<li class="desktop-icon">
<a href="javascript:void(0);" onclick="openWindow('archives-window')">
<img src="https://img.naturaleki.one/lock/save.png">
<span>Archives</span>
</a>
</li>
</div>
<!-- 第二行 -->
<div class="icon-row">
<li class="desktop-icon">
<a href="javascript:void(0);" onclick="openWindow('tag-window')">
<img src="https://img.naturaleki.one/lock/tags.png">
<span>Tags</span>
</a>
</li>
<li class="desktop-icon">
<a href="javascript:void(0);" onclick="openWindow('search-window')">
<img src="https://img.naturaleki.one/lock/search1.png">
<span>Search</span>
</a>
</li>
</div>
<div class="empty-space"></div>
<!-- 第三行 -->
<div class="icon-row">
<li class="desktop-icon">
<a href="/about/">
<img src="https://img.naturaleki.one/lock/drug.png">
<span>About</span>
</a>
</li>
<li class="desktop-icon">
<a href="/link/">
<img src="https://img.naturaleki.one/lock/friends.png">
<span>Friends</span>
</a>
</li>
</div>
<div class="icon-row">
<li class="desktop-icon">
<a href="javascript:void(0);" onclick="openWindow('changelog-window')">
<img src="https://img.naturaleki.one/lock/brush.png">
<span>Changelog</span>
</a>
</li>
<li class="desktop-icon">
<a href="javascript:void(0);" onclick="openWindow('feed-window')">
<img src="https://img.naturaleki.one/lock/daybit.png">
<span>Daybit</span>
</a>
</li>
</div>
<div class="empty-space"></div>
<div class="icon-row">
<li class="desktop-icon">
<a href="javascript:void(0);" onclick="openWindow('gift-window')">
<img src="https://img.naturaleki.one/lock/candy.png">
<span>Gifts</span>
</a>
</li>
<li class="desktop-icon">
<a href="/index.xml">
<img src="https://img.naturaleki.one/lock/rss.png">
<span>RSS</span>
</a>
</li>
</ul>
</div>
手机端菜单的html基本原样复制,只需要微调一下css,我取消了手机上的归档窗口和changelog窗口弹出,改为正常切换页面。
@media (max-width: 768px) {
.desktop-icons {
align-items: flex-end;
}
.desktop-icon img {
background: var(--color-codebg);
}
}
移动设备样式适配
给平板和手机分别调整了不同的弹窗尺寸。
/* 更小屏幕的适配 (例如:手机屏幕) */
@media (max-width: 640px) {
/* 窗口大小进一步缩小 */
#feed-window.window {
width: 60%; /* 宽度增加 */
height: 50%;
top: 10%;
left: 5%;
}
#gift-window.window {
width: 80%; /* 宽度增加 */
height: 45%;
top: 10%;
left: 5%;
}
#tag-window.window {
width: 60%; /* 宽度增加 */
height: 50%;
top: 10%;
left: 5%;
}
#extra-window.window {
width: 60%;
height: 20%;
top: 10%;
left: 30%;
}
/* 标题文字调整 */
.window-header {
font-size: 16px;
}
/* 关闭按钮的大小 */
.close-btn {
width: 23px;
height: 23px;
border: 1px solid var(--color-primary);
}
.close-btn img {
width: 18px;
height: 18px;
}
/* 内容区文字大小 */
.feed-item {
font-size: 12px; /* 调整内容文字大小 */
}
}
@media (min-width: 640px) and (max-width: 1024px) {
/* 窗口适配 */
#feed-window.window {
width: 40%; /* 调整宽度 */
height: 47%;
top: 15%; /* 距顶部适配 */
left: 10%; /* 距左侧适配 */
}
#search-window.window {
width: 80%;
max-width: 1080px;
height: 55%;
top: 43%;
left: 10%;
}
#tag-window.window {
width: 30%;
max-width: 480px;
height: 40%;
top: 30%;
left: 45%;
}
#gift-window.window {
width: 50%;
max-width: 480px;
height: 43%;
top: 15%;
right: 20%;
}
/* 标题文字调整 */
.window-header {
font-size: 18px; /* 字体略大一些 */
}
/* 关闭按钮大小调整 */
.close-btn{
width: 25px;
height: 25px; /* 适中大小 */
border: 1px solid var(--color-primary);
}
.close-btn img {
width: 20px;
height: 20px;
}
/* 内容区文字大小 */
.feed-item {
font-size: 14px; /* 中等字体大小 */
}
}
小彩蛋
给博客添加了一个小彩蛋弹窗,找天堂错误文件家的小狗玩(?)就可以看见啦,窗口和css代码与前面的大同小异,就直接略过了,在这里贴一下触发相关js代码。
let clickCount = 0; // 点击计数器
const targetCount = 3; // 目标点击次数
function extraWindow(windowId) {
clickCount++; // 每次点击计数加一
console.log(`当前点击次数: ${clickCount}`); // 打印调试信息
if (clickCount === targetCount) {
const window = document.getElementById(windowId);
if (window) {
window.style.display = 'block'; // 显示窗口
}
clickCount = 0; // 重置计数器(可选,根据需求修改)
}
}
每次装修博客都致力于捣鼓一些华而不实的功能。
博客滚动条样式修改
给弹窗滚动条染色,染完后就顺便把博客的也一起染了。
::-webkit-scrollbar {
width: 10px; /* 滚动条宽度 */
height: 7px; /* 横向滚动条高度 */
}
::-webkit-scrollbar-track {
background: #f6f8fa; /* 滚动条轨道背景色 */
}
::-webkit-scrollbar-thumb {
background: #8aa2d3; /* 滚动条滑块颜色 */
border-radius: 10px;
}
.body {
scrollbar-color: #8aa2d3 #f6f8fa; /* 滑块颜色 | 轨道颜色 */
}
暂时隐藏了博客黑夜模式切换,默认的颜色样式实在是太不好看了,如果我哪天有心情自己设计一个配色方案再放出来吧。
后记
去年年底看完ChatGPT生成的年度总结,90%的聊天都是我在拿博客代码砸它,然后它再拿更多的代码砸回来,就这么反反复复打太极直到达到我想要的效果。当时的我立下了今年绝对不要再装修博客的誓言,然后这个誓言在2025的第二天就被打破了,还好当时没许一辈子不然我的一辈子在半个月后就结束了(……)不过这次装修完短期内是真的不想装修了!如果这篇能带来一点参考价值的话是我极大的荣幸!