aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/components/ScheduleInteractive.astro
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/ScheduleInteractive.astro')
-rw-r--r--src/components/ScheduleInteractive.astro14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/components/ScheduleInteractive.astro b/src/components/ScheduleInteractive.astro
index 19a3f59..4c31d99 100644
--- a/src/components/ScheduleInteractive.astro
+++ b/src/components/ScheduleInteractive.astro
@@ -26,6 +26,16 @@
const escapeHtml = (s) =>
s.replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
+ // 行番号ではなく、日付と名称からアンカーIDを作る(予定を追加してもリンクが変わらないように)。
+ function stableId(input: string): string {
+ let hash = 2166136261;
+ for (let i = 0; i < input.length; i++) {
+ hash ^= input.charCodeAt(i);
+ hash = Math.imul(hash, 16777619);
+ }
+ return (hash >>> 0).toString(36);
+ }
+
function initSchedule() {
const calendarEl = document.getElementById('schedule-calendar');
const detailsEl = document.getElementById('schedule-day-details');
@@ -39,7 +49,7 @@
const entries = [];
function collect(table, type) {
- table.querySelectorAll('tbody tr').forEach((row, i) => {
+ table.querySelectorAll('tbody tr').forEach((row) => {
const cells = row.querySelectorAll('td');
if (cells.length < 3) return;
const dateText = cells[0].textContent.trim();
@@ -47,7 +57,7 @@
const timeText = cells[2].textContent.trim();
// 出典欄はリンク先URLで判定するため、HTML を保持する(textContent には href が入らない)。
const source = cells[4] ? cells[4].innerHTML : '';
- const rowId = `${type}-row-${i}`;
+ const rowId = `${type}-${stableId(`${dateText}|${name}`)}`;
row.id = rowId;
let category = MEETING_ICON;