アンカーリンクはページのリロード(再読み込み)はされずにジャンプしますがこれをページを再読み込みしてクリックした要素まで移動する方法です。
JavaScriptで使える関数「window.location.href」を使用すれば簡単!と思ったのですが、なかなか指定した要素まで移動できなかったので備忘録です。
アンカーリンクを普通に使うならページジャンプで特に問題はないはずなので、少しマニアックな記事です。
前提としてWordpressを使用したサイトで、jQueryで実装しました。
この記事ではアンカーリンクの使い方は省略します。
この記事の目次
ページ内アンカーリンクにリロードで移動する
JavaScriptで使えるwindow.location.hrefプロパティーに遷移先のページURLを指定すれば画面遷移が可能です。
違うページに画面遷移させたい場合はそのURLを入れるだけで簡単なのですが、今回はページ内リンクで使うという少しハックな方法です。
記事内のHタグを目次にし、アンカーリンクで移動できるようにしている場合などにこれをジャンプではなくリロードで読み込ませたかったのです。
なぜ?というと長くなるのですが、サイドバーに設置した目次が機能しなかったのでページごと読みなおせれば動くじゃないか!と思ったからです…
ただ思った以上に「ページ内アンカーリンクへの移動+再読み込み」は難しいです。
ページ内リンクのクリック時に何かを実行する
ベースとなるコードからご紹介します。
今回Wordpressでの使用を考えていましたので、$がjQueryになっています。
//↓a hrefタグ内のid:#○○がクリックされた時 jQuery('a[href^="#"]').on('click',function() { //↓hrefには「#○○部分が入る」 var href= jQuery(this).attr("href"); //↓window.location.hrefでリロードする。 window.location.href = 移動したいURL; });
jQueryを使って目次などのページ内リンクにジャンプしたりスクロールして移動したりする時に使う定番のコードを少し編集しました。
このコードの処理部分でwindow.location.hrefを使ってクリックされた目次にページリロード(再読み込み)で移動しようというのが今回の内容です。
window.location.replaceを使ってみたのですがうまく動作しませんでしたのでwindow.location.hrefを使う方法でやってみました。
リロードで移動できなかったコード
こうすればページ内リンクにリロードで移動できるだろう...
と思ったコードがことごとく失敗しましたのでご紹介します。
失敗コードその1
jQuery('a[href^="#"]').on('click',function() { var href= jQuery(this).attr("href"); window.location.href = "./"+href; });
一般的な「サイトトップ/記事ページ」というパスにアンカーリンクの#idを足してリロードすれば良くない?と思ったのですが、普通にジャンプしてしまいダメでした。
ブラウザに入力されるURLは移動したい先と同じなのですが、リロードできません。
失敗コードその2
jQuery('a[href^="#"]').on('click',function() { var href= jQuery(this).attr("href"); var url=location.href; window.location.href = url + href; });
では現在のページURLに#idを足せば?
と思ったのですが、やはりリロードではなく普通にジャンプしてしまいました。
失敗コードその3
//これではブラウザに#が追加されてしまう。 jQuery('a[href^="#"]').on('click',function() { var href= jQuery(this).attr("href"); var url=location.href; window.location.href = url + href; window.location.reload(); });
window.location.reloadを使ってページ内リンクがある位置を再読み込みしてみたところ上手くいきました。
が、このコードではクリックの度にURLに「http://~/#id1#id2#id3...」とパラメータが付与され続けるため1回目しか機能しません。
ページ内リンクにリロードで移動するコード
すみません長くなってしまいました。
長いこと格闘していたのでダメだった例も見ていただきたくて・・・
リロードでの移動に成功したコードはコチラです。
jQuery('a[href^="#"]').on('click',function() { var href= jQuery(this).attr("href"); window.location.href = ".//"+href; });
ハックな方法かもしれませんが、パスに「.//」を指定したところ上手くいきました!
わざと違うクエリを付与すればリロード(再読み込み)でアンカーリンクに移動できるっぽいです・w・
2023.8.15 追記
バックスラッシュ(/)はJavaScriptのエスケープ文字なので、今回のように文字列リテラルを入力したい時は2回書かないといけなかっただけかもです。
ただ、このコードだと一度ジャンプした後にページリロードという動作になります。
こんな感じです。惜しい...
ページ内リンクのジャンプを無効化する
そこでもう一工夫。
ページ内のアンカーリンクがクリックされた時にブラウザによって勝手にジャンプやスクロールされないようにします。
JavaScriptやCSSを使う方法がありますが、どれもしっくりきませんでした。
そこで同要素がクリックされた時にfalseを返してあげるとうまくいきました!
jQuery('a[href^="#"]').on('click',function() { return false; }); jQuery('a[href^="#"]').on('click',function() { var href= jQuery(this).attr("href"); window.location.href = ".//"+href; });
ページ内リンクをクリックした時にfalseを返すコードを1行目に追加しました。
実際にアンカーリンクにリロードで移動する様子が以下のGIFです。
ページ内リンク(目次)への移動をジャンプやスクロールではなく、ページリロードでアンカーリンクの位置まで移動できました。
これにて終了・w・
最後に、動作確認をした時のサイト環境をメモしておきます。
サイト環境
- XAMPPでWordPressをローカル環境に構築したテストサイト。
- WordPressテーマは無料テーマ「Cocoon」を使用。
- アンカーリンク(目次)の生成には「Easy Table of Contents」を使用。
- 「Easy Table of Contents」のスムーズスクロールの機能はOFF。
- PHPバージョン:8.xx
上記のサイト環境で、アンカーリンクにリロードで移動できました。
ただサイト環境によっては当記事のコードを使ってもジャンプやスムーズスクロールが生きたままになるかもしれません...原因はテーマかプラグインだと思います。
まとめ
以上、ページ内アンカーリンクにリロード(再読み込み)で移動する方法でした。
手元のiPhoneでも動作確認したのですが、あくまでハックな方法ですので使用する際は自己責任でお願いします...
当方JavaScript勉強中でもっとうまくいく方法があるかもしれませんが、どうしてもサイドバーに設置した目次をリロードで移動したかったのでこうなりました。