added 代码折叠 修复bug

This commit is contained in:
Vaica committed 2026-01-30 22:18:19 +08:00
1 parent c115c7c0fb
commit 33a6ce2d85
4 files changed
+212 -35

No files matched your search

@@ -88,27 +88,38 @@ async function processFiles(dir) {
window.artalk.on('list-loaded', function() { window.artalk.on('list-loaded', function() {
// 检查是否有 AI 评论数据 // 检查是否有 AI 评论数据
if (window.artalkConfig.aiComment && !document.querySelector('.atk-ai-comment')) { if (window.artalkConfig.aiComment && !document.querySelector('.atk-ai-comment')) {
// 创建 DOM 结构 var listBody = document.querySelector('.atk-list-body') || document.querySelector('.atk-list');
var aiDiv = document.createElement('div');
aiDiv.className = 'atk-comment atk-ai-comment'; if (listBody) {
aiDiv.innerHTML = `...`; // 填充 HTML // 避免同时出现“此时无声胜有声”
var noComment = document.querySelector('.atk-list-no-comment');
if (noComment) noComment.style.display = 'none';
// 插入到列表头部 // 创建 DOM 结构
var listBody = document.querySelector('.atk-list-body'); var aiDiv = document.createElement('div');
if (listBody) listBody.prepend(aiDiv); aiDiv.className = 'atk-comment atk-ai-comment';
aiDiv.innerHTML = `...`; // 填充 HTML
// 简单的打字机效果
const contentEl = aiDiv.querySelector('.ai-content-text'); // 插入到列表头部
const text = window.artalkConfig.aiComment.content; listBody.prepend(aiDiv);
let i = 0;
function type() { // ... (打字机效果)
if (i < text.length) {
contentEl.textContent += text.charAt(i);
i++;
setTimeout(type, Math.random() * 30 + 20);
}
} }
setTimeout(type, 500); }
});
```
## 4. 适配 PJAX
由于博客使用了 PJAX,页面切换时需要重新初始化 Artalk。我们将初始化逻辑封装在 `initArtalk` 函数中,并在 `pjax:complete` 事件中调用。
```javascript
// mypjax.js
document.addEventListener("pjax:complete", function () {
// ...
// 重载评论
if (typeof window.initArtalk === 'function') {
window.initArtalk();
} }
}); });
``` ```
+94
View File
@@ -196,8 +196,102 @@ code {
background-color: #f6f8fa; /* Day Mode */ background-color: #f6f8fa; /* Day Mode */
color: #24292e; color: #24292e;
border: 1px solid #d0d7de; border: 1px solid #d0d7de;
/* Hide scrollbar but allow scrolling */
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE 10+ */
} }
pre::-webkit-scrollbar,
code::-webkit-scrollbar {
display: none; /* Chrome/Safari/Webkit */
}
/* Code Folding */
.code-fold-container {
position: relative;
margin-bottom: 1rem;
border-radius: 4px; /* Optional: match highlight radius */
}
.code-fold-container.collapsed {
max-height: 360px;
overflow: hidden;
}
/* Ensure inner code blocks don't have bottom margin when wrapped */
.code-fold-container .highlight,
.code-fold-container pre {
margin-bottom: 0;
}
.code-expand-btn {
display: none;
position: absolute;
bottom: -7px;
left: -146px;
width: 100%;
height: 80px;
text-align: center;
/* Gradient Background for Fade Effect */
background: linear-gradient(180deg, rgba(246, 248, 250, 0) 0%, rgba(246, 248, 250, 0.9) 50%, rgba(246, 248, 250, 1) 100%);
border: none;
color: #586069;
cursor: pointer;
z-index: 10;
font-size: 13px;
transition: all 0.2s;
align-items: center;
justify-content: center;
padding-top: 20px;
}
/* Show button when collapsed */
.code-fold-container.collapsed .code-expand-btn {
display: flex;
}
/* Button Pill Style */
.code-expand-btn span {
background: rgba(255, 255, 255, 0.9);
padding: 6px 16px;
border-radius: 20px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
display: flex;
align-items: center;
border: 1px solid rgba(0,0,0,0.05);
transition: all 0.2s ease;
}
.code-expand-btn:hover span {
background: #fff;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.12);
color: #0366d6;
}
/* Dark Mode Support */
[data-theme="dark"] .code-expand-btn {
background: linear-gradient(180deg, rgba(40, 42, 54, 0) 0%, rgba(40, 42, 54, 0.9) 50%, rgba(40, 42, 54, 1) 100%);
color: #f8f8f2;
}
[data-theme="dark"] .code-expand-btn span {
background: rgba(68, 71, 90, 0.8);
border-color: rgba(255,255,255,0.05);
}
[data-theme="dark"] .code-expand-btn:hover span {
background: #44475a;
color: #8be9fd;
}
/* Artalk AI Comment Integration */
.atk-list.has-ai-comment .atk-list-no-comment {
display: none !important;
}
[data-theme="dark"] pre, [data-theme="dark"] pre,
[data-theme="dark"] code { [data-theme="dark"] code {
background-color: #282a36; /* Night Mode */ background-color: #282a36; /* Night Mode */
+86 -16
View File
@@ -114,12 +114,19 @@ window.initArtalk = function() {
// Inject AI Comment // Inject AI Comment
window.artalk.on('list-loaded', function() { window.artalk.on('list-loaded', function() {
if (window.artalkConfig.aiComment && !document.querySelector('.atk-ai-comment')) { if (window.artalkConfig.aiComment) {
var listBody = document.querySelector('.atk-list-body') || document.querySelector('.atk-list'); // Force hide "No comments" message via CSS class
if (listBody) { var list = document.querySelector('.atk-list');
var aiData = window.artalkConfig.aiComment; if (list) {
var aiDiv = document.createElement('div'); list.classList.add('has-ai-comment');
aiDiv.className = 'atk-comment atk-ai-comment'; }
if (!document.querySelector('.atk-ai-comment')) {
var listBody = document.querySelector('.atk-list-body') || document.querySelector('.atk-list');
if (listBody) {
var aiData = window.artalkConfig.aiComment;
var aiDiv = document.createElement('div');
aiDiv.className = 'atk-comment atk-ai-comment';
// Initially empty content for typewriter effect // Initially empty content for typewriter effect
aiDiv.innerHTML = ` aiDiv.innerHTML = `
<div class="atk-avatar"> <div class="atk-avatar">
@@ -158,7 +165,8 @@ window.initArtalk = function() {
setTimeout(type, 500); setTimeout(type, 500);
} }
} }
}); }
});
// Artalk 初始化完成后,再加载弹幕 (If available) // Artalk 初始化完成后,再加载弹幕 (If available)
if (typeof isMobile === 'function' && !isMobile() && window.loadBarrager) { if (typeof isMobile === 'function' && !isMobile() && window.loadBarrager) {
@@ -190,7 +198,7 @@ function initCodeCopy() {
const copyBtn = document.createElement('button'); const copyBtn = document.createElement('button');
copyBtn.className = 'copy-code-btn'; copyBtn.className = 'copy-code-btn';
copyBtn.innerHTML = '<i class="fa fa-copy"></i>'; // 使用 FontAwesome 图标 copyBtn.innerHTML = '<i class="ri-file-copy-2-line"></i>'; // 使用 RemixIcon
copyBtn.title = '复制代码'; copyBtn.title = '复制代码';
// 样式 (建议放到 CSS 文件中) // 样式 (建议放到 CSS 文件中)
@@ -218,15 +226,15 @@ function initCodeCopy() {
copyBtn.addEventListener('click', () => { copyBtn.addEventListener('click', () => {
const code = codeBlock.innerText; const code = codeBlock.innerText;
navigator.clipboard.writeText(code).then(() => { navigator.clipboard.writeText(code).then(() => {
copyBtn.innerHTML = '<i class="fa fa-check"></i>'; copyBtn.innerHTML = '<i class="ri-check-line"></i>';
setTimeout(() => { setTimeout(() => {
copyBtn.innerHTML = '<i class="fa fa-copy"></i>'; copyBtn.innerHTML = '<i class="ri-file-copy-2-line"></i>';
}, 2000); }, 2000);
Qmsg.success("代码复制成功"); Qmsg.success("代码复制成功");
}).catch(err => { }).catch(err => {
console.error('复制失败:', err); console.error('复制失败:', err);
copyBtn.innerHTML = '<i class="fa fa-times"></i>'; copyBtn.innerHTML = '<i class="ri-close-line"></i>';
Qmsg.error("复制失败"); Qmsg.error("复制失败");
}); });
}); });
@@ -235,11 +243,73 @@ function initCodeCopy() {
}); });
} }
// 页面加载完成后初始化 (Merged into main DOMContentLoaded listener) // 代码折叠功能
// document.addEventListener('DOMContentLoaded', function() { function initCodeFold() {
// initCodeCopy(); const threshold = 360;
// initDescriptionHitokoto();
// }); // Helper to wrap element
const wrap = (el, wrapper) => {
el.parentNode.insertBefore(wrapper, el);
wrapper.appendChild(el);
};
// 1. Process .highlight blocks (Hugo generated)
document.querySelectorAll('.highlight').forEach(hl => {
if (hl.closest('.code-fold-container')) return; // Avoid double processing
// Check height
if (hl.scrollHeight > threshold) {
const wrapper = document.createElement('div');
wrapper.className = 'code-fold-container collapsed';
// Wrap the highlight block
wrap(hl, wrapper);
const btn = document.createElement('button');
btn.className = 'code-expand-btn';
// Use FontAwesome for reliability
btn.innerHTML = '<span><i class="fa fa-chevron-down" style="margin-right: 4px;"></i> 展开代码</span>';
btn.addEventListener('click', () => {
wrapper.classList.remove('collapsed');
btn.remove();
});
wrapper.appendChild(btn);
}
});
// 2. Process bare pre blocks (Fallback)
document.querySelectorAll('.post-content > pre').forEach(pre => {
if (pre.parentNode.classList.contains('highlight')) return;
if (pre.closest('.code-fold-container')) return;
if (pre.closest('.code-wrapper')) return; // Old wrapper check
if (pre.scrollHeight > threshold) {
const wrapper = document.createElement('div');
wrapper.className = 'code-fold-container collapsed';
wrap(pre, wrapper);
const btn = document.createElement('button');
btn.className = 'code-expand-btn';
btn.innerHTML = '<span><i class="fa fa-chevron-down" style="margin-right: 4px;"></i> 展开代码</span>';
btn.addEventListener('click', () => {
wrapper.classList.remove('collapsed');
btn.remove();
});
wrapper.appendChild(btn);
}
});
}
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
initCodeCopy();
initCodeFold();
initDescriptionHitokoto();
});
// 初始化个人描述一言切换 // 初始化个人描述一言切换
function initDescriptionHitokoto() { function initDescriptionHitokoto() {
+2
View File
@@ -175,6 +175,8 @@ document.addEventListener("pjax:complete", function () {
pjax_reload() pjax_reload()
// 初始化代码复制 // 初始化代码复制
initCodeCopy() initCodeCopy()
// 初始化代码折叠
initCodeFold()
// 重载评论 // 重载评论
if (typeof window.initArtalk === 'function') { if (typeof window.initArtalk === 'function') {
window.initArtalk(); window.initArtalk();