diff options
| -rw-r--r-- | src/components/ScheduleInteractive.astro | 14 |
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) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[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; |
