かぁくん本紀自作CMS・自作サーバーにて運用中
ブログ・ホームページ >

【HTML・JS】Aタグでhrefのリンク先を読み込まずにアドレスバーのURLだけ変更する

公開日時: 2024-10-18 00:48:31更新日時: 2024-11-08 15:41:45タイトル通りです。
SPA(シングルページアプリケーション)でも、SEO面や、リンクにマウスホバーしたときのURL表示などの都合から、AタグのhrefにはURLを入れておきたい、そして、そのAタグをクリックしたときの動作は、ブラウザのアドレスバーのURLはhrefに指定した通り変わるけど、内部的にはページ遷移せずにAjaxで済ませたいというときのテクニックを(ほぼ自分用に)まとめておきます。

要点

やることはシンプルで、ポイントは以下の4つだけです。
  • Aタグのhrefには、普通にリンク先のURLを記載する
  • リンク先のURLに直接アクセスされたときはhtaccess等で内部リダイレクトを設定しといてよしなに処理する
  • onclickでevent.preventDefaultを呼び出してhrefのURLを無視させる
  • history.pushStateかhistory.replaceStateでURLを書き換える

仕組み

順に説明します。
まあ、JSの関数の使い方はMDN見てもらったほうが早いと思うので、ここには書きません()

Aタグのhrefには、普通にリンク先のURLを記載する

Aタグのhrefには普通にリンク先のURLを記載しておきます。
これにより、リンクにマウスをホバーさせたときには、通常のリンクと同様にリンク先のURLが表示されます。

ちなみに、(もう検索エンジンのクローラーですらonloadで実行されるJSは一通り実行してからインデックス登録していく時代ですが、)JSの無効化されているブラウザでは、このAタグをクリックすると、普通にリンク先に飛びます。
まあ、この記事のテクニックが役立つのは専らSPAなので、JSの使えないブラウザは考慮する必要もないと思います()

リンク先のURLに直接アクセスされたときはhtaccess等で内部リダイレクトを設定しといてよしなに処理する

後述のhistory.pushStateやhistory.replaceStateを使うと、書き換えた後のURLが普通にブラウザの履歴に残るので、そこから直接書き換え後URLにアクセスされた場合のことも考えておく必要があります。

SPAの場合、htaccess辺りを使ってトップページにでも内部リダイレクトして、トップページでは、例えばPHPなら$_SERVER["PATH_INFO"]などを使ってPATH_INFOからリダイレクト元を判定するなり、うまいこと処理してあげればいいと思います。

onclickでevent.preventDefaultを呼び出してhrefのURLを無視させる

Aタグはonclickイベントの中でevent.preventDefault関数を実行すると、hrefに応じてリンク先に飛ぶ動作がキャンセルされます。

なお、
<a href="hoge.html" onclick="fuga(); event.preventDefault();">ほげほげ</a>
のように、event.preventDefaultの前に別の関数を実行していると、その関数の中でエラーが発生して処理が止まってしまった場合、リンク先に飛ぶ動作がキャンセルされなくなってしまいます。
<a href="hoge.html" onclick="event.preventDefault(); fuga();">ほげほげ</a>
のように、event.preventDefaultはonclickの中で最初に呼び出すのが基本になります。

もちろん、JSコード中で、
document.getElementById("hoge").onclick = function (event) {
    event.preventDefault();
}
のようにonclickの処理を設定しても、リンク先に飛ぶ動作はキャンセル可能です。

history.pushStateかhistory.replaceStateでURLを書き換える

ページ遷移せずにURLを書き換えるには、history.pushState、または、history.replaceStateを使います。
前者を使用した場合、書き換え前のURLが履歴に残る(=ブラウザの戻るボタンを押すと書き換え前のURLにページ遷移する)ので、ブラウザの戻るボタンが押されたときにページ遷移せずなにかやりたい場合は、window.onpopstateに関数を紐付けて、そこで history.pushState(null, null, null); を実行してURL書き換えを拒否することも可能です。

URLを書き換えたあとは、普通にAjaxとかで鯖からデータを取ってきて画面に書き出してあげればOKですね(*`ᴗ´*)
この記事のタグ:
HTMLJavascript

この記事へのコメント