Skip to content

Commit 0663338

Browse files
committed
暂存
1 parent 4253a9f commit 0663338

File tree

7 files changed

+409
-54
lines changed

7 files changed

+409
-54
lines changed

assets/css/masonry.css

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#md-content {
2+
margin-top: 40px;
3+
}
4+
5+
.md-card {
6+
background: #fff;
7+
border-radius: 8px;
8+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
9+
overflow: hidden;
10+
transition: all 0.3s ease;
11+
}
12+
13+
.md-card:hover {
14+
transform: translateY(-5px);
15+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
16+
}
17+
18+
.md-card[data-link] {
19+
cursor: pointer;
20+
}
21+
22+
.md-card[data-link]:hover {
23+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
24+
}
25+
26+
.md-header {
27+
padding: 15px;
28+
background: #f8f9fa;
29+
}
30+
31+
.md-header h2 {
32+
margin: 0;
33+
font-size: 1.2em;
34+
color: #333;
35+
}
36+
37+
.md-bg-image {
38+
width: 100%;
39+
height: 200px;
40+
object-fit: cover;
41+
margin-top: 10px;
42+
}
43+
44+
.md-description {
45+
padding: 15px;
46+
color: #666;
47+
font-size: 0.9em;
48+
line-height: 1.5;
49+
}
50+
51+
.md-link {
52+
padding: 15px;
53+
text-align: right;
54+
border-top: 1px solid #eee;
55+
}
56+
57+
.md-link a {
58+
color: #007bff;
59+
text-decoration: none;
60+
font-weight: 500;
61+
}
62+
63+
.md-link a:hover {
64+
text-decoration: underline;
65+
}

assets/js/main.js

Lines changed: 81 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,4 @@
11
(function () {
2-
// Functions
3-
// =========================================================================
4-
/**
5-
* Adds event listeners to change active stylesheet and restore previously
6-
* activated stylesheet on reload.
7-
*
8-
* @example
9-
*
10-
* This link:
11-
* <a href="#" data-link-title="Foo">Foo</a>
12-
* Will active this existing link:
13-
* <link rel="stylesheet alternate" title="Foo" href="..." >
14-
*
15-
* @example
16-
*
17-
* This link:
18-
* <a href="#" data-link-href="path/to/file.css">Bar</a>
19-
* Will activate this existing link:
20-
* <link rel="stylesheet alternate" title="[someID]" href="path/to/file.css" >
21-
* Or generate this active link:
22-
* <link rel="stylesheet" title="Bar" href="path/to/file.css" >
23-
*/
242
function initStyleSwitcher() {
253
var isInitialzed = false;
264
var sessionStorageKey = "activeStylesheetHref";
@@ -58,20 +36,16 @@
5836
'"])'
5937
);
6038

61-
// Remove "alternate" keyword
6239
activeElm.setAttribute(
6340
"rel",
6441
(activeElm.rel || "").replace(/\s*alternate/g, "").trim()
6542
);
6643

67-
// Force enable stylesheet (required for some browsers)
6844
activeElm.disabled = true;
6945
activeElm.disabled = false;
7046

71-
// Store active style sheet
7247
sessionStorage.setItem(sessionStorageKey, activeHref);
7348

74-
// Disable other elms
7549
for (var i = 0; i < inactiveElms.length; i++) {
7650
var elm = inactiveElms[i];
7751

@@ -88,17 +62,14 @@
8862
}
8963
}
9064

91-
// CSS custom property ponyfil
9265
if ((window.$docsify || {}).themeable) {
9366
window.$docsify.themeable.util.cssVars();
9467
}
9568
}
9669

97-
// Event listeners
9870
if (!isInitialzed) {
9971
isInitialzed = true;
10072

101-
// Restore active stylesheet
10273
document.addEventListener("DOMContentLoaded", function () {
10374
var activeHref = sessionStorage.getItem(sessionStorageKey);
10475

@@ -107,7 +78,6 @@
10778
}
10879
});
10980

110-
// Update active stylesheet
11181
document.addEventListener("click", function (evt) {
11282
var dataHref = evt.target.getAttribute("data-link-href");
11383
var dataTitle = evt.target.getAttribute("data-link-title");
@@ -139,7 +109,6 @@ async function loadAllMd() {
139109
const response = await fetch(treeUrl);
140110
const { tree } = await response.json();
141111

142-
// 2. 过滤 en/products/**/.md
143112
const mdPaths = tree
144113
?.filter(
145114
(i) =>
@@ -149,13 +118,11 @@ async function loadAllMd() {
149118
)
150119
?.map((i) => i.path);
151120

152-
// 3. 构建目录树
153121
const directoryTree = {};
154122
mdPaths.forEach((path) => {
155123
const parts = path.replace(/^en\/products\//, "").split("/");
156124
let current = directoryTree;
157125

158-
// 构建目录结构
159126
for (let i = 0; i < parts.length - 1; i++) {
160127
const part = parts[i];
161128
if (!current[part]) {
@@ -164,7 +131,6 @@ async function loadAllMd() {
164131
current = current[part].subdirs;
165132
}
166133

167-
// 添加文件
168134
const fileName = parts[parts.length - 1];
169135
const parentDir = parts
170136
.slice(0, -1)
@@ -176,22 +142,19 @@ async function loadAllMd() {
176142
}
177143
});
178144

179-
// 4. 渲染导航
180145
const navElement = document.getElementById("product-folders");
181146
navElement.innerHTML = "<h3>产品分类</h3><ul></ul>";
182147
const ulElement = navElement.querySelector("ul");
183148

184-
// 检查目录是否包含子文件夹
185149
function hasSubFolders(node) {
186150
return Object.values(node.subdirs).some((item) => item.type === "folder");
187151
}
188152

189-
// 递归渲染目录
190153
function renderDirectory(dir, parentElement, level = 0) {
191154
Object.entries(dir).forEach(([name, data]) => {
192155
const li = document.createElement("li");
193156
li.className = "category-item";
194-
li.style.paddingLeft = `${level * 2}em`; // 每层增加2个字符宽度的缩进
157+
li.style.paddingLeft = `${level * 2}em`;
195158

196159
if (data.type === "folder") {
197160
// 这是一个目录
@@ -213,16 +176,13 @@ async function loadAllMd() {
213176
const subfolderWrapper = li.querySelector(".subfolder-wrapper");
214177
const subfolder = li.querySelector(".subfolder");
215178

216-
// 点击文件夹名称时加载该文件夹下的所有 md 文件
217179
folderName.addEventListener("click", () => {
218-
// 移除所有选中状态
219180
document.querySelectorAll(".category-item").forEach((item) => {
220181
item.classList.remove("active");
221182
});
222-
// 添加当前选中状态
183+
223184
li.classList.add("active");
224185

225-
// 收集当前文件夹及其子文件夹下的所有 md 文件
226186
const allFiles = [];
227187
function collectFiles(node) {
228188
if (node.type === "file") {
@@ -234,7 +194,6 @@ async function loadAllMd() {
234194
collectFiles(data);
235195
showAllMd(allFiles);
236196

237-
// 如果有子文件夹,处理展开/折叠
238197
if (hasSubdirs) {
239198
const isExpanded =
240199
subfolderWrapper.classList.contains("expanded");
@@ -247,7 +206,6 @@ async function loadAllMd() {
247206
renderDirectory(data.subdirs, subfolder, level + 1);
248207
}
249208
} else {
250-
// 这是一个文件,不显示在导航中
251209
return;
252210
}
253211

@@ -257,7 +215,6 @@ async function loadAllMd() {
257215

258216
renderDirectory(directoryTree, ulElement);
259217

260-
// 自动展开并选中第一个目录
261218
const firstFolder = ulElement.querySelector(".folder-item");
262219
if (firstFolder) {
263220
const folderName = firstFolder.querySelector(".folder-name");
@@ -287,12 +244,13 @@ async function showAllMd(paths) {
287244
const md = await fetch(rawUrl).then((r) => r.text());
288245
const name = p.split("/").pop();
289246

290-
// 提取元数据
291247
const metadata = extractMetadata(md);
292248

293249
// 渲染内容
294250
html += `
295-
<div class="md-document">
251+
<div class="md-card" ${
252+
metadata.link ? `data-link="${metadata.link}"` : ""
253+
}>
296254
<div class="md-header">
297255
<h2>${metadata.title || name}</h2>
298256
${
@@ -312,17 +270,91 @@ async function showAllMd(paths) {
312270
: ""
313271
}
314272
</div>
315-
<hr/>
316273
`;
317274
}
318275
mdContent.innerHTML = html;
276+
277+
278+
const cards = document.getElementsByClassName("md-card");
279+
Array.from(cards).forEach((card) => {
280+
const link = card.getAttribute("data-link");
281+
if (link) {
282+
card.style.cursor = "pointer";
283+
card.addEventListener("click", (e) => {
284+
285+
if (e.target.tagName === "A") {
286+
return;
287+
}
288+
window.open(link, "_blank");
289+
});
290+
}
291+
});
292+
293+
initMasonry();
319294
} catch (error) {
320295
console.error("加载文件内容失败:", error);
321296
mdContent.innerHTML = "<p>加载失败,请重试</p>";
322297
}
323298
}
324299

325-
// 提取元数据函数
300+
function initMasonry() {
301+
const container = document.getElementById("md-content");
302+
const cards = container.getElementsByClassName("md-card");
303+
const cardWidth = 400;
304+
const gap = 20;
305+
306+
function calculateLayout() {
307+
const containerWidth = container.clientWidth;
308+
const columnCount = Math.floor((containerWidth + gap) / (cardWidth + gap));
309+
return columnCount;
310+
}
311+
312+
function layout() {
313+
const columnCount = calculateLayout();
314+
const columns = Array(columnCount)
315+
.fill()
316+
.map(() => []);
317+
const columnHeights = Array(columnCount).fill(0);
318+
319+
container.style.position = "relative";
320+
container.style.height = "auto";
321+
322+
Array.from(cards).forEach((card) => {
323+
const minHeightIndex = columnHeights.indexOf(Math.min(...columnHeights));
324+
columns[minHeightIndex].push(card);
325+
columnHeights[minHeightIndex] += card.offsetHeight + gap;
326+
});
327+
328+
let currentX = 0;
329+
columns.forEach((column, columnIndex) => {
330+
let currentY = 0;
331+
column.forEach((card) => {
332+
card.style.position = "absolute";
333+
card.style.width = `${cardWidth}px`;
334+
card.style.left = `${currentX}px`;
335+
card.style.top = `${currentY}px`;
336+
currentY += card.offsetHeight + gap;
337+
});
338+
currentX += cardWidth + gap;
339+
});
340+
341+
container.style.height = `${Math.max(...columnHeights)}px`;
342+
}
343+
344+
let resizeTimer;
345+
window.addEventListener("resize", () => {
346+
clearTimeout(resizeTimer);
347+
resizeTimer = setTimeout(layout, 100);
348+
});
349+
350+
const images = container.getElementsByTagName("img");
351+
Array.from(images).forEach((img) => {
352+
img.addEventListener("load", layout);
353+
});
354+
355+
layout();
356+
}
357+
326358
function extractMetadata(md) {
327359
const metadata = {
328360
title: null,
@@ -331,7 +363,6 @@ function extractMetadata(md) {
331363
link: null,
332364
};
333365

334-
// 尝试匹配 YAML front matter
335366
const yamlMatch = md.match(/^---\s*\n([\s\S]*?)\n---/);
336367
if (yamlMatch) {
337368
const yamlContent = yamlMatch[1];
@@ -372,7 +403,6 @@ function extractMetadata(md) {
372403
return metadata;
373404
}
374405

375-
// 页面加载完成后执行
376406
document.addEventListener("DOMContentLoaded", () => {
377407
loadAllMd();
378408
});

en/products/display/eink/heltec_eink_display_list.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
---
22
title: "Heltec LoRa Gateway 产品差异对比"
33
description: |
4-
Heltec 的 LoRa Gateway 系列设备支持标准 LoRaWAN,
5-
拥有完善的文档、出色的 RF 设计和阻抗匹配能力131313131
6-
131313131。
4+
Heltec 的 LoRa Gateway 系列设备支持标准 LoRaWAN,
5+
拥有完善的文档、出色的 RF 设计和阻抗匹配能力131313131
6+
131313131。
77
bgImage: "https://resource.heltec.cn/img/docs/lora_gateway/ht_m02.jpg"
88
link: "https://heltec.cn/project/htcc-ab01"
99
---

0 commit comments

Comments
 (0)