
西村 祐真
@variant3a
Alpine.jsでScroll Spyを実装する
2023-01-22
views: 424

Alpine.jsでScroll Spy機能を実装する方法が他のサイトになかったため、自分で実装してみた。
なお、ParserはCommonmarkを使用しているため、ヘッダーの出力結果が異なる場合がある。
環境
- Laravel 9.x
- Livewire 2.x
- TailwindCSS 3
- Alpine.js 3
- Commonmark
コード
<!-- Anchor link list -->
<div class="hidden row-auto p-2 mb-1 space-y-1 font-mono bg-white rounded shadow md:block sm:mb-3 dark:bg-zinc-700 ring-1 ring-black/5"
x-data="{ position: '', links: document.querySelectorAll(`[id^='content-']`) }">
<template x-for="link in links">
<a class="flex justify-between w-full p-1 break-all rounded hover:bg-teal-500/50 text-neutral-700 dark:text-neutral-200 hover:text-white first:rounded-t last:rounded-b"
x-bind:href="`#${link.id}`"
x-bind:key="link.id"
x-text="link.parentElement.innerText"
x-on:scroll.window="position = [...links].filter(v => v.getBoundingClientRect().top > 0)[0].id"
x-bind:class="{ 'bg-teal-500/50 text-white': position === link.id }"
data-turbo="false">
</a>
</template>
</div>
<!-- Contents -->
<div class="markdown">
<h2>
<a id="content-1-Header" href="#content-1-Header" class="heading-permalink" aria-hidden="true" title="Permalink"></a>
1. Header
</h2>
</div>
説明
x-data
でコンテンツ側からヘッダーのidを取得する<template>
タグでforeachで回すx-bind:href
でヘッダーのidのリンクを作成するx-text
でヘッダーのテキストを取得するx-on:scroll.window
でwindowがscrollした時に、ヘッダー表示位置が一番高い(=top > 0
)ものを絞り込み、最初の(= 一番上の)elementのidを取得するx-bind:class
で一番上のヘッダーが現在のリンクなら、スタイルを設定する
注意
環境でhotwired/turbo
を使用している場合、アンカーリンクが効かない場合がある。その場合はdata-turbo="false"
を設定しよう。
2023-01-22
views: 424
most viewed

Laradockを利用したLaravel環境構築
@variant3a
2022-06-09
views: 533

BrowserSyncを使おう
@variant3a
2022-06-09
views: 430

Office365UserコネクタのSearchUserV2の制限
@variant3a
2022-07-14
views: 476

Laravelのルーティング順による404エラーの対処法
@variant3a
2022-07-16
views: 783

「"仮想DOMは速い"という神話を完全に終わりにしよう」
@variant3a
2022-07-19
views: 579