随机跳转

This commit is contained in:
biss committed 2026-07-18 19:49:13 +08:00
1 parent ecadaaaaf1
commit 22a8c5b424
4 files changed
+199 -3

No files matched your search

+114
View File
@@ -0,0 +1,114 @@
---
import { articles } from "../data/articles";
import { photoTopics } from "../data/photos";
import { timeline } from "../data/timeline";
const memoryGroups = [
{
type: "photo",
items: photoTopics.flatMap((topic) =>
topic.photos
.filter((photo) => photo.image)
.map((photo) => ({
href: photo.image,
title: photo.title,
caption: [topic.title, photo.caption].filter(Boolean).join(" · ")
}))
)
},
{
type: "article",
items: articles.map((article) => ({
href: article.sourceUrl,
title: article.title
}))
},
{
type: "timeline",
items: timeline.map((moment, index) => ({
href: `/timeline/#moment-${index + 1}`,
title: `${moment.date} · ${moment.title}`
}))
}
];
---
<button
class="button random-memory-button"
id="random-memory-button"
type="button"
data-memory-groups={JSON.stringify(memoryGroups)}
aria-describedby="random-memory-hint"
>
<i class="fa-solid fa-shuffle" aria-hidden="true"></i>
<span>随便看看</span>
</button>
<span class="sr-only" id="random-memory-hint">随机打开一张照片、一篇文章或一个时间节点</span>
<span class="sr-only" id="random-memory-status" aria-live="polite"></span>
<dialog class="random-photo-dialog" id="random-photo-dialog" aria-labelledby="random-photo-caption">
<button class="random-photo-close" type="button" aria-label="关闭照片">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</button>
<figure>
<img id="random-photo-image" alt="" />
<figcaption id="random-photo-caption"></figcaption>
</figure>
</dialog>
<script>
interface MemoryItem {
href: string;
title: string;
caption?: string;
}
interface MemoryGroup {
type: "photo" | "article" | "timeline";
items: MemoryItem[];
}
const button = document.querySelector<HTMLButtonElement>("#random-memory-button");
const status = document.querySelector<HTMLElement>("#random-memory-status");
const photoDialog = document.querySelector<HTMLDialogElement>("#random-photo-dialog");
const photoImage = document.querySelector<HTMLImageElement>("#random-photo-image");
const photoCaption = document.querySelector<HTMLElement>("#random-photo-caption");
const photoClose = document.querySelector<HTMLButtonElement>(".random-photo-close");
let previousHref = "";
photoClose?.addEventListener("click", () => photoDialog?.close());
photoDialog?.addEventListener("click", (event) => {
if (event.target === photoDialog) photoDialog.close();
});
photoDialog?.addEventListener("close", () => photoImage?.removeAttribute("src"));
button?.addEventListener("click", () => {
const groups = JSON.parse(button.dataset.memoryGroups ?? "[]") as MemoryGroup[];
const availableGroups = groups.filter((group) => group.items.length > 0);
if (availableGroups.length === 0) return;
const group = availableGroups[Math.floor(Math.random() * availableGroups.length)];
const candidates = group.items.filter((item) => item.href !== previousHref);
const pool = candidates.length > 0 ? candidates : group.items;
const item = pool[Math.floor(Math.random() * pool.length)];
previousHref = item.href;
if (status) status.textContent = `这次抽到:${item.title}`;
if (group.type === "photo") {
if (photoDialog && photoImage && photoCaption && typeof photoDialog.showModal === "function") {
photoImage.src = item.href;
photoImage.alt = item.title;
photoCaption.textContent = [item.title, item.caption].filter(Boolean).join(" — ");
photoDialog.showModal();
return;
}
}
if (group.type === "article") {
window.open(item.href, "_blank", "noopener,noreferrer");
return;
}
window.location.assign(item.href);
});
</script>
+2
View File
@@ -1,6 +1,7 @@
--- ---
import BaseLayout from "../layouts/BaseLayout.astro"; import BaseLayout from "../layouts/BaseLayout.astro";
import OnThisDay from "../components/OnThisDay.astro"; import OnThisDay from "../components/OnThisDay.astro";
import RandomMemory from "../components/RandomMemory.astro";
import { galleryIntro, photoTopics } from "../data/photos"; import { galleryIntro, photoTopics } from "../data/photos";
import { featuredMessage, messages, messagesIntro } from "../data/messages"; import { featuredMessage, messages, messagesIntro } from "../data/messages";
import { people, peopleIntro } from "../data/people"; import { people, peopleIntro } from "../data/people";
@@ -25,6 +26,7 @@ const previewPeople = people.slice(0, 6);
<p>{site.subtitle}</p> <p>{site.subtitle}</p>
<div class="hero-actions"> <div class="hero-actions">
<a class="button primary" href="/timeline/">翻开回忆</a> <a class="button primary" href="/timeline/">翻开回忆</a>
<RandomMemory />
<a class="button" href="/messages/">写一句话</a> <a class="button" href="/messages/">写一句话</a>
</div> </div>
</div> </div>
+3 -3
View File
@@ -19,9 +19,9 @@ import { timeline, timelineIntro } from "../data/timeline";
<div class="section-inner"> <div class="section-inner">
<div class="timeline"> <div class="timeline">
{ {
timeline.map((moment) => timeline.map((moment, index) =>
moment.href ? ( moment.href ? (
<a class="moment moment-link" href={moment.href}> <a class="moment moment-link" id={`moment-${index + 1}`} href={moment.href}>
<time>{moment.date}</time> <time>{moment.date}</time>
<div> <div>
<h3>{moment.title}</h3> <h3>{moment.title}</h3>
@@ -29,7 +29,7 @@ import { timeline, timelineIntro } from "../data/timeline";
</div> </div>
</a> </a>
) : ( ) : (
<article class="moment"> <article class="moment" id={`moment-${index + 1}`}>
<time>{moment.date}</time> <time>{moment.date}</time>
<div> <div>
<h3>{moment.title}</h3> <h3>{moment.title}</h3>
Loaded 3 of 4 files, more files were not shown because too many files have changed in this diff. Show more