修改1
This commit is contained in:
+141
-15
@@ -1,16 +1,26 @@
|
||||
<section class="on-this-day-band" aria-labelledby="on-this-day-title">
|
||||
<div class="section-inner on-this-day-shell" data-on-this-day>
|
||||
<div class="memory-date-card" aria-hidden="true">
|
||||
<span data-memory-month>今日</span>
|
||||
<strong data-memory-day>--</strong>
|
||||
<small>北京时间</small>
|
||||
<div class="memory-calendar" aria-label="记忆日历">
|
||||
<div class="memory-calendar-head">
|
||||
<div class="memory-calendar-nav">
|
||||
<button type="button" data-calendar-previous aria-label="上一个月">←</button>
|
||||
<strong data-calendar-label aria-live="polite">本月</strong>
|
||||
<button type="button" data-calendar-next aria-label="下一个月">→</button>
|
||||
</div>
|
||||
<button class="memory-calendar-today" type="button" data-calendar-today>回到今天</button>
|
||||
</div>
|
||||
<div class="memory-calendar-weekdays" aria-hidden="true">
|
||||
<span>日</span><span>一</span><span>二</span><span>三</span><span>四</span><span>五</span><span>六</span>
|
||||
</div>
|
||||
<div class="memory-calendar-grid" data-calendar-grid></div>
|
||||
<p class="memory-calendar-legend"><span aria-hidden="true"></span>圆点表示这一天收录了班级记忆</p>
|
||||
</div>
|
||||
|
||||
<div class="on-this-day-content">
|
||||
<div class="on-this-day-heading">
|
||||
<div>
|
||||
<p class="eyebrow">ON THIS DAY · 那年今日</p>
|
||||
<h2 id="on-this-day-title">今天,记忆翻到了这一页</h2>
|
||||
<h2 id="on-this-day-title" data-memory-title>今天,记忆翻到了这一页</h2>
|
||||
</div>
|
||||
<p data-memory-summary aria-live="polite">正在寻找同月同日的班级记忆……</p>
|
||||
</div>
|
||||
@@ -50,26 +60,49 @@
|
||||
day: "numeric"
|
||||
}).formatToParts(new Date());
|
||||
const dateValues = Object.fromEntries(dateParts.map((part) => [part.type, part.value]));
|
||||
const month = Number(dateValues.month);
|
||||
const day = Number(dateValues.day);
|
||||
const todayMonth = Number(dateValues.month);
|
||||
const todayDay = Number(dateValues.day);
|
||||
const currentYear = Number(dateValues.year);
|
||||
const monthDay = `${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
||||
const matches = onThisDayMemories.filter((memory) => memory.monthDay === monthDay);
|
||||
const visibleMatches = matches.slice(0, 6);
|
||||
let calendarYear = currentYear;
|
||||
let calendarMonth = todayMonth;
|
||||
let selectedMonth = todayMonth;
|
||||
let selectedDay = todayDay;
|
||||
|
||||
const monthLabel = root.querySelector<HTMLElement>("[data-memory-month]");
|
||||
const dayLabel = root.querySelector<HTMLElement>("[data-memory-day]");
|
||||
const titleLabel = root.querySelector<HTMLElement>("[data-memory-title]");
|
||||
const summary = root.querySelector<HTMLElement>("[data-memory-summary]");
|
||||
const grid = root.querySelector<HTMLElement>("[data-memory-grid]");
|
||||
const empty = root.querySelector<HTMLElement>("[data-memory-empty]");
|
||||
const calendarLabel = root.querySelector<HTMLElement>("[data-calendar-label]");
|
||||
const calendarGrid = root.querySelector<HTMLElement>("[data-calendar-grid]");
|
||||
const previousButton = root.querySelector<HTMLButtonElement>("[data-calendar-previous]");
|
||||
const nextButton = root.querySelector<HTMLButtonElement>("[data-calendar-next]");
|
||||
const todayButton = root.querySelector<HTMLButtonElement>("[data-calendar-today]");
|
||||
|
||||
if (monthLabel) monthLabel.textContent = `${month}月`;
|
||||
if (dayLabel) dayLabel.textContent = String(day).padStart(2, "0");
|
||||
const getMonthDay = (month: number, day: number) =>
|
||||
`${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
||||
|
||||
const getMemories = (month: number, day: number) => {
|
||||
const monthDay = getMonthDay(month, day);
|
||||
return onThisDayMemories.filter((memory) => memory.monthDay === monthDay);
|
||||
};
|
||||
|
||||
const renderMemories = (month: number, day: number) => {
|
||||
selectedMonth = month;
|
||||
selectedDay = day;
|
||||
const matches = getMemories(month, day);
|
||||
const visibleMatches = matches.slice(0, 6);
|
||||
const isToday = month === todayMonth && day === todayDay;
|
||||
|
||||
if (titleLabel) {
|
||||
titleLabel.textContent = isToday
|
||||
? "今天,记忆翻到了这一页"
|
||||
: `${month}月${day}日,记忆翻到了这一页`;
|
||||
}
|
||||
|
||||
if (summary) {
|
||||
summary.textContent = matches.length
|
||||
? `${month}月${day}日,找到了 ${matches.length} 条跨越不同年份的班级记忆。`
|
||||
: `${month}月${day}日,今天暂时没有同月同日的记录。`;
|
||||
: `${month}月${day}日,暂时没有同月同日的记录。`;
|
||||
}
|
||||
|
||||
if (grid) {
|
||||
@@ -129,5 +162,98 @@
|
||||
}
|
||||
|
||||
if (empty) empty.hidden = matches.length > 0;
|
||||
};
|
||||
|
||||
const renderCalendar = () => {
|
||||
if (calendarLabel) calendarLabel.textContent = `${calendarYear}年${calendarMonth}月`;
|
||||
if (!calendarGrid) return;
|
||||
|
||||
const fragment = document.createDocumentFragment();
|
||||
const firstWeekday = new Date(calendarYear, calendarMonth - 1, 1).getDay();
|
||||
const daysInMonth = new Date(calendarYear, calendarMonth, 0).getDate();
|
||||
|
||||
for (let index = 0; index < firstWeekday; index += 1) {
|
||||
const spacer = document.createElement("span");
|
||||
spacer.className = "memory-calendar-spacer";
|
||||
spacer.setAttribute("aria-hidden", "true");
|
||||
fragment.append(spacer);
|
||||
}
|
||||
|
||||
for (let day = 1; day <= daysInMonth; day += 1) {
|
||||
const matches = getMemories(calendarMonth, day);
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.dataset.calendarDay = String(day);
|
||||
button.className = "memory-calendar-day";
|
||||
button.setAttribute(
|
||||
"aria-label",
|
||||
matches.length ? `${calendarMonth}月${day}日,有${matches.length}条记忆` : `${calendarMonth}月${day}日`
|
||||
);
|
||||
|
||||
if (matches.length) {
|
||||
button.classList.add("has-memory");
|
||||
button.dataset.memoryCount = String(matches.length);
|
||||
}
|
||||
if (calendarMonth === selectedMonth && day === selectedDay) {
|
||||
button.classList.add("is-selected");
|
||||
button.setAttribute("aria-pressed", "true");
|
||||
}
|
||||
if (calendarYear === currentYear && calendarMonth === todayMonth && day === todayDay) {
|
||||
button.classList.add("is-today");
|
||||
}
|
||||
|
||||
const number = document.createElement("span");
|
||||
number.textContent = String(day);
|
||||
button.append(number);
|
||||
|
||||
if (matches.length) {
|
||||
const dot = document.createElement("i");
|
||||
dot.setAttribute("aria-hidden", "true");
|
||||
button.append(dot);
|
||||
}
|
||||
|
||||
fragment.append(button);
|
||||
}
|
||||
|
||||
calendarGrid.replaceChildren(fragment);
|
||||
};
|
||||
|
||||
calendarGrid?.addEventListener("click", (event) => {
|
||||
const target = event.target;
|
||||
if (!(target instanceof Element)) return;
|
||||
const button = target.closest<HTMLButtonElement>("[data-calendar-day]");
|
||||
if (!button) return;
|
||||
|
||||
renderMemories(calendarMonth, Number(button.dataset.calendarDay));
|
||||
renderCalendar();
|
||||
});
|
||||
|
||||
previousButton?.addEventListener("click", () => {
|
||||
calendarMonth -= 1;
|
||||
if (calendarMonth === 0) {
|
||||
calendarMonth = 12;
|
||||
calendarYear -= 1;
|
||||
}
|
||||
renderCalendar();
|
||||
});
|
||||
|
||||
nextButton?.addEventListener("click", () => {
|
||||
calendarMonth += 1;
|
||||
if (calendarMonth === 13) {
|
||||
calendarMonth = 1;
|
||||
calendarYear += 1;
|
||||
}
|
||||
renderCalendar();
|
||||
});
|
||||
|
||||
todayButton?.addEventListener("click", () => {
|
||||
calendarYear = currentYear;
|
||||
calendarMonth = todayMonth;
|
||||
renderMemories(todayMonth, todayDay);
|
||||
renderCalendar();
|
||||
});
|
||||
|
||||
renderMemories(todayMonth, todayDay);
|
||||
renderCalendar();
|
||||
}
|
||||
</script>
|
||||
|
||||
+203
-54
@@ -225,56 +225,16 @@ h1 {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 150px minmax(0, 1fr);
|
||||
grid-template-columns: minmax(280px, 1fr) minmax(0, 2fr);
|
||||
gap: clamp(28px, 5vw, 64px);
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.memory-date-card {
|
||||
position: sticky;
|
||||
top: 26px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(55, 109, 90, 0.2);
|
||||
border-radius: 14px;
|
||||
background: #fffdf7;
|
||||
box-shadow: 0 18px 42px rgba(39, 55, 52, 0.11);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.memory-date-card span,
|
||||
.memory-date-card small {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.memory-date-card span {
|
||||
padding: 8px 12px;
|
||||
background: var(--green);
|
||||
color: #fffdf7;
|
||||
font-size: 14px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.memory-date-card strong {
|
||||
display: block;
|
||||
padding: 12px 12px 2px;
|
||||
color: var(--ink);
|
||||
font-family: Georgia, "Times New Roman", serif;
|
||||
font-size: 62px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.memory-date-card small {
|
||||
padding: 8px 12px 13px;
|
||||
color: var(--muted);
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
|
||||
.on-this-day-heading {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(240px, 0.8fr);
|
||||
gap: clamp(20px, 4vw, 52px);
|
||||
align-items: end;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 12px;
|
||||
align-items: start;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
@@ -287,6 +247,162 @@ h1 {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.memory-calendar {
|
||||
position: sticky;
|
||||
top: 26px;
|
||||
padding: 18px;
|
||||
border: 1px solid rgba(31, 43, 42, 0.12);
|
||||
border-radius: 14px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
box-shadow: 0 8px 28px rgba(39, 55, 52, 0.06);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.memory-calendar-head,
|
||||
.memory-calendar-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.memory-calendar-head {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.memory-calendar-nav {
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.memory-calendar-nav strong {
|
||||
min-width: 126px;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.memory-calendar-nav button,
|
||||
.memory-calendar-today {
|
||||
min-height: 38px;
|
||||
border: 1px solid var(--line);
|
||||
background: #fffdf7;
|
||||
color: var(--ink);
|
||||
font: inherit;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
transition: border-color 160ms ease, background 160ms ease, color 160ms ease;
|
||||
}
|
||||
|
||||
.memory-calendar-nav button {
|
||||
width: 38px;
|
||||
padding: 0;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.memory-calendar-today {
|
||||
width: 100%;
|
||||
padding: 7px 13px;
|
||||
border-radius: 999px;
|
||||
color: var(--green);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.memory-calendar-nav button:hover,
|
||||
.memory-calendar-today:hover {
|
||||
border-color: var(--green);
|
||||
background: var(--green);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.memory-calendar-weekdays,
|
||||
.memory-calendar-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, minmax(0, 1fr));
|
||||
gap: 7px;
|
||||
}
|
||||
|
||||
.memory-calendar-weekdays {
|
||||
margin-bottom: 7px;
|
||||
color: var(--muted);
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.memory-calendar-day,
|
||||
.memory-calendar-spacer {
|
||||
min-width: 0;
|
||||
aspect-ratio: 1.45;
|
||||
}
|
||||
|
||||
.memory-calendar-day {
|
||||
position: relative;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
align-content: center;
|
||||
gap: 3px;
|
||||
padding: 4px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 9px;
|
||||
background: rgba(244, 247, 238, 0.72);
|
||||
color: var(--muted);
|
||||
font: inherit;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
transition: transform 150ms ease, border-color 150ms ease, background 150ms ease, color 150ms ease;
|
||||
}
|
||||
|
||||
.memory-calendar-day:hover {
|
||||
transform: translateY(-1px);
|
||||
border-color: rgba(55, 109, 90, 0.3);
|
||||
color: var(--green);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.memory-calendar-day.has-memory {
|
||||
color: var(--ink);
|
||||
background: rgba(232, 168, 76, 0.12);
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.memory-calendar-day i {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 50%;
|
||||
background: var(--coral);
|
||||
}
|
||||
|
||||
.memory-calendar-day.is-today {
|
||||
border-color: rgba(55, 109, 90, 0.55);
|
||||
}
|
||||
|
||||
.memory-calendar-day.is-selected {
|
||||
border-color: var(--green);
|
||||
background: var(--green);
|
||||
color: #fffdf7;
|
||||
box-shadow: 0 6px 16px rgba(55, 109, 90, 0.2);
|
||||
}
|
||||
|
||||
.memory-calendar-day.is-selected i {
|
||||
background: #f3cf8b;
|
||||
}
|
||||
|
||||
.memory-calendar-legend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
margin: 12px 0 0;
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.memory-calendar-legend > span {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--coral);
|
||||
}
|
||||
|
||||
.memory-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
@@ -296,7 +412,7 @@ h1 {
|
||||
.memory-card {
|
||||
min-height: 190px;
|
||||
display: grid;
|
||||
grid-template-columns: 150px minmax(0, 1fr);
|
||||
grid-template-columns: 120px minmax(0, 1fr);
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(31, 43, 42, 0.12);
|
||||
border-radius: 12px;
|
||||
@@ -2366,7 +2482,21 @@ h2 {
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
@media (max-width: 1040px) and (min-width: 821px) {
|
||||
.memory-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.memory-calendar {
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 820px) {
|
||||
.memory-calendar {
|
||||
position: static;
|
||||
}
|
||||
|
||||
body:has(.score-sidebar) {
|
||||
padding-bottom: 86px;
|
||||
}
|
||||
@@ -2659,6 +2789,34 @@ h2 {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.memory-calendar {
|
||||
margin-inline: -4px;
|
||||
padding: 13px 9px;
|
||||
}
|
||||
|
||||
.memory-calendar-head {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.memory-calendar-nav {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.memory-calendar-today {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.memory-calendar-weekdays,
|
||||
.memory-calendar-grid {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.memory-calendar-day,
|
||||
.memory-calendar-spacer {
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
display: grid;
|
||||
}
|
||||
@@ -2673,15 +2831,6 @@ h2 {
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
.memory-date-card {
|
||||
position: static;
|
||||
width: 104px;
|
||||
}
|
||||
|
||||
.memory-date-card strong {
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.memory-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user