mizdra's blog

ぽよぐらみんぐ

閉じている details 要素に `#fragment` でジャンプして、ジャンプと同時に展開したい

最近用語集のようなページを作る機会があった。それぞれの用語の名前と説明がバーっと並んでて、説明部分は <details> 要素で隠されている。用語の名前をクリックすると <details> が展開されて、説明部分が読める、といった感じ。

JavaScript, C++, Python という3つの用語の説明が並んでいる。それぞれの用語の説明は details 要素で構成されていて、JavaScript と Python は展開されていて、C++ は展開されていない。
用語集ページの例

他のページから特定の用語の説明に飛べるように、用語を表す要素それぞれに id 属性が振ってある。例えば https://glossary.example.com/#javascript という URL でアクセスすると、「JavaScript」の用語がある位置にスクロールした状態で、用語集ページを開ける。

ただ (一部ブラウザで) https://glossary.example.com/#javascript でアクセスしても、JavaScript の説明の欄が閉じたままで困っていた。その用語の説明が見たいがためにしてきているので、最初から説明の欄は展開されていて欲しい。

Auto-expand details elements

実は、まさにこれを実現するための機能が標準化されている (「Auto-expand details elements」と呼ばれてる)。

厳密にはこの機能は、#id-or-name による navigation が発生した時だけでなく、Text Fragment (#:~:text=...) による navigation や、ページ検索の際にも、<details> 要素の自動展開を行う仕様となってる。

Chrome や Edge では実装済みで、Safari や Firefox では未実装。そのため、Chrome や Edge であれば、 https://glossary.example.com/#javascript でアクセスすれば、最初から JavaScript の説明欄が展開された状態でページを開ける。

shim

そのうち他のブラウザでも実装が進むだろうけど、待っていられないので shim *1 を書いた。

以下のデモページからお試しいただけます。

やってることはシンプルで、ページ表示時と <a> 要素をクリックした時に、閉じている <details> 要素に fragment navigation しようとしてたら展開するだけ。

注意点としては、「Auto-expand details elements」機能の全ての挙動を模倣している訳では無いということ。先述したように「Auto-expand details elements」機能にはページ検索や Scroll to Text Fragment で <details> 要素にヒットした時に、その <details> 要素を自動展開する挙動があるが、shim ではその挙動までは再現していない。そうした挙動まで再現するのは大変すぎるし、id:mizdra は別に必要としてないので。

あと View フレームワークによっては、DOMContentLoaded イベントリスナーが上手く設定できなくて、そのままでは shim が利用できないかも。また動的に <a> 要素がページに挿入される場合は、その <a> 要素にも a.addEventListener("click", ...) する必要がある。アプリケーションごとに事情が変わってくると思うので、アプリケーションごとに上手くやってください。

ポケットモンスター・ポケモン・Pokémon・は任天堂・クリーチャーズ・ゲームフリークの登録商標です.

当ブログは @mizdra 個人により運営されており, 株式会社ポケモン及びその関連会社とは一切関係ありません.