AstroのViewTransition使用時のJavaScript最適解
具体的な話
AstroのViewTransitionを使って画面遷移を行うと、よくハマる問題として『既存のJavaScriptが動かない』がある。 ただこれは
document.addEventListener("astro:page-load", () => { /* ここに処理を書く */})このような感じでJavaScriptの実行タイミングを遅らせることで解決できるのだが、今日はその addEventListener の話。
"astro:page-load" については、画面遷移が終わったら発火されるイベントと思ってもらえればと。
画面を表示している最中にJavaScriptを動かさないことで正常に機能させている。
結論から書いてしまうと、『addEventListenerの記述は1箇所で済ませる』これに尽きる。 それはモバイルでも正常に動かすため。
具体的には以下のようなレイアウトがあると想定して</body>の直前。
</main> <Footer /> <!-- ここ --> </body></html>この1箇所にまとめてしまう。 このタイミングで書くと操作したいオブジェクトがないときもJavaScriptが動いてしまうのだが、それはif文で回避する。
例えば当サイト検索ページ用のJavaScriptの例。if文で”search”が存在するときだけ処理する。
const searchFunc = () => { // 検索UI const searchEl = document.getElementById("search"); if (searchEl) { // 検索UI表示ちなみに検索はPagefindを使っている。
同じく当サイトブログ記事のカテゴリタブ表示の例。こちらもif文で”category-nav”が存在するときだけ処理する。
const showCategoryNavFunc = () => { // カテゴリナビ const nav = document.getElementById("category-nav"); if (nav) { nav.style.visibility = "visible"; } };補足としてカテゴリタブの表示を遅らせている理由は、 『モバイルのSafariで表示したときカテゴリタブ構築中のガチャガチャが見えてしまうから』である。
あとは”astro:page-load”に登録するだけ。この1箇所のみ。
document.addEventListener("astro:page-load", () => { searchFunc(); showCategoryNavFunc(); });広告の処理も同様にこのタイミングで行っています。
やりがちなNG例
個別のページで”astro:page-load”に登録や解除を行う
個別ページで登録・解除を行うと、遷移後にイベントが再登録されない可能性がある。 特にモバイルで起こる。
例えば『1回目のaddEventListenerは機能するけど、別ページに遷移したときのaddEventListenerが初回だけ動かない』 などといった不思議な症状で悩んでしまう。PCのブラウザでは再現しないので気が付きにくい。
まとめ
『addEventListenerは1箇所で行う』そうしないとモバイルで不具合が起こる。
これはAstroのViewTransitionを使うときのJavaScriptベストプラクティスです。 ViewTransitionを使わないなら違うのかも。