【JavaScript】画面遷移とは?やり方や注意点を初心者向けにわかりやすく解説
はじめに
JavaScriptを用いてウェブページの画面遷移を実装する場面は、開発を始めると早い段階で登場しやすいテーマです。
たとえば、あるボタンをクリックしたら別のページに飛ばしたい、あるいは動的にHTML要素を切り替えて、ページ全体を読み込み直さずに次の表示へ移りたい、といったケースが考えられます。
こうした画面遷移は、シンプルなものなら location.href
で移動するだけですが、実際の開発ではもっと柔軟なアプローチが必要になることも多いでしょう。
そこで本記事では、JavaScriptを使ったさまざまな画面遷移の方法を整理しながら、実務で気をつけたいポイントを解説していきます。
初心者の方にとって、画面遷移という言葉だけではイメージが湧きにくいかもしれませんが、具体的なコード例を交えながら説明するので安心してください。
ブラウザが提供している仕組みや、React Routerなどのライブラリの活用方法などをわかりやすく紹介します。
この記事を読むとわかること
- JavaScriptで画面遷移を行う基本的な方法
- シンプルなリロード型の画面遷移と動的な画面遷移の違い
- シングルページアプリケーション (SPA) における画面遷移の考え方
- history APIやReact Routerを利用する際の基本的なコード例
- 実務で役立つ注意点やよくある落とし穴
ここから順を追って解説していきます。
画面遷移とは何かを整理する
JavaScriptでの画面遷移を理解するために、まず「画面遷移」という言葉が何を指すのか整理しましょう。
画面遷移とは、ざっくり言えば「ユーザーが操作した結果、サイト内の異なるコンテンツへ移動する」ことです。
ブラウザ上でページのURLが変わるタイプの遷移もあれば、同じURLのままで表示内容だけを切り替えるものもあります。
ブラウザの標準的な画面遷移とJavaScript
通常、リンクをクリックすると、ブラウザは指定されたURLのページを新たに読み込みます。
これはブラウザが元々備えている仕組みであり、JavaScriptを使わなくてもリンク要素だけで完結します。
一方、JavaScriptを使って遷移させる手段としては、window.location
を操作する方法がよく知られています。
ただ、さらに高度なUIを提供するケースでは、画面全体をリロードせずに要素を部分的に切り替えたり、履歴管理を巧みに扱ったりする必要が出てくるでしょう。
画面全体を再読み込みする遷移 vs. 局所的に描画を切り替える遷移
画面遷移を大きく分けると、次の2種類に分類しやすいです。
- 画面全体を再読み込みする遷移
- 一部コンテンツだけを切り替える動的な遷移
前者は伝統的でシンプルですが、ページのリロードが都度発生します。
後者は、たとえばReactやVue.jsなどのフレームワークが提供する仕組みを活用して、URL自体はそのまま、または履歴だけを操作しながら、ページを切り替えるように見せかける手法です。
初心者の方は、まず画面リロードが伴う方法と、リロードを伴わない方法を区別すると理解しやすいかもしれません。
シンプルな画面遷移:locationオブジェクト
JavaScriptで画面を移動させるもっとも単純な方法は、location
オブジェクトを直接書き換えることです。
やり方は2つほどあります。
location.href
を変更する方法location.replace()
を使う方法
いずれも、ページを読み込み直すためのリクエストが発生し、サーバー側に新しいページを求めにいきます。
location.href で遷移する
いちばんよく使われるやり方として、location.href
を書き換える方法があります。
// ボタンクリックなどのイベントで実行する例 document.getElementById("moveButton").addEventListener("click", function () { location.href = "https://example.com/next.html"; });
これを実行すると、現在のページを離れて https://example.com/next.html
に移動します。
ポイントとしては、ブラウザの「戻る」ボタンを押せば以前のページに戻れることです。
ユーザーが以前のページに戻りたい状況が想定されるときは、こちらが使いやすいといえます。
location.replace() で遷移する
location.href
と似ていますが、location.replace()
を使う方法もあります。
document.getElementById("replaceButton").addEventListener("click", function () { location.replace("https://example.com/replace.html"); });
replace
メソッドは、ブラウザの履歴を上書きするため、ユーザーが「戻る」ボタンを押しても、元のページには戻れません。
ログアウト処理など、絶対に前のページに戻させたくない場合に活用されるケースが多いです。
location.href
と location.replace()
は見た目の挙動は似ていますが、履歴の扱いが異なる点が重要です。
リロードを伴わない画面遷移(SPA)
次に、リロードを伴わずにページが切り替わるように見せる方法について解説します。
たとえば、ボタンを押したら画面全体を読み込み直すのではなく、部分的に表示するコンテンツを切り替え、かつURLの末尾だけ変更する、といった処理をJavaScriptで行うやり方です。
SPA(Single Page Application)とは何か
SPA (Single Page Application) は、文字通り1つのHTMLページの中で画面の状態を切り替えていくアーキテクチャです。
実際にはJavaScriptでページを操作し、画面の一部のみを更新します。
URLは内部的に書き換わりますが、サーバーへのフルリクエストが走らないので、動作が軽快に感じられたり、ユーザーが途切れない操作体験を得られたりします。
実務でのSPAの活用シーン
SPAがよく使われるのは、たとえば以下のようなケースです。
- 動きの多い管理画面やチャットツール
- 継続的に操作が行われるウェブアプリ(地図アプリなど)
- 一部のコンテンツを瞬時に書き換えるUIを実装したいとき
こうしたアプリケーションではページの再読み込みが重なると、使いづらさを感じる人が増えます。
SPAであれば、背景で非同期通信(Ajaxなど)を走らせつつ、必要な部分だけアップデートすることが可能です。
history APIを使った画面遷移
SPAの文脈でよく使われるのが、history API と呼ばれるブラウザの仕組みです。
history.pushState()
などを使うと、実際にページをリロードすることなく、URLや履歴を変更できます。
history.pushState() の基本
pushState
メソッドは、次のように記述します。
history.pushState( { some: "data" }, "", "/new-page" );
これは画面の状態を表すオブジェクト(例では { some: "data" }
)と、ブラウザのタイトル(上の例では空文字列)、そして新しいURL( /new-page
)を指定しています。
この処理を行うと、ブラウザのアドレスバーが https://example.com/new-page
のように書き換わりますが、リロードはされません。
つまり「URLが変わったように見せつつ、実際の画面はJavaScriptで制御する」という状態を作れるわけです。
popstate イベント
pushState
や replaceState
などで履歴を操作した後、ユーザーがブラウザの「戻る」ボタンを押すと、popstate
イベントが発火します。
これを利用することで、前の画面表示をJavaScriptで復元したり、特定のUIを呼び出したりできます。
以下のコード例は、ユーザーが「戻る」ボタンを押したときに、何らかの処理を実行するイメージを示しています。
window.addEventListener("popstate", function (event) { console.log("popstateで復元", event.state); // event.state には pushState/replaceState で渡したデータが入っている // ここでUIを切り替えるなどの処理を実装する });
このように、JavaScriptだけで履歴を自由に操りながら、リロードを挟まずに画面を切り替える仕組みが整っているのです。
具体例:Vanilla JSでSPAライクな画面遷移を実装
ライブラリを使わず、純粋なJavaScript(Vanilla JS)でSPAライクな遷移を実装してみましょう。
下記の例では、メイン領域(<div id="app">
)の中身だけを切り替えて、URLも変わるようにしています。
シンプルなHTML構造とルーティングテーブル
まず、HTML側は以下のようにごくシンプルにしておきます。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>SPA-like example</title> </head> <body> <nav> <a href="/" data-link>Home</a> <a href="/about" data-link>About</a> <a href="/contact" data-link>Contact</a> </nav> <div id="app"></div> <script src="app.js"></script> </body> </html>
data-link
属性を付与したナビゲーションリンクを配置しておきます。
JavaScript側でリンククリックを捕捉して画面切り替え
続いて、JavaScript( app.js
)でリンクのクリックイベントを拾い、pushState
しつつ #app
の中身を差し替えます。
// ルートと表示するコンテンツを紐付ける例 const routes = { "/": "これはホーム画面です。", "/about": "これはアバウトページです。", "/contact": "ここはお問い合わせページです。", }; // メインコンテンツを描画する関数 function renderContent(path) { const content = routes[path] || "ページが見つかりません。"; document.getElementById("app").textContent = content; } // 現在のURLに対応する画面を表示する関数 function navigateTo(path) { // URLをpushStateで更新 history.pushState({}, "", path); // コンテンツを切り替え renderContent(path); } // 初期表示 renderContent(window.location.pathname); // ページを離れずにリンクをクリックした際に画面を切り替える document.addEventListener("click", (e) => { const link = e.target.closest("[data-link]"); if (!link) return; e.preventDefault(); // 通常の画面遷移を阻止 navigateTo(link.getAttribute("href")); }); // 戻る・進むボタン対応 window.addEventListener("popstate", () => { renderContent(window.location.pathname); });
この例では、リンクをクリックすると e.preventDefault()
で通常の遷移を止め、navigateTo
関数が history.pushState
でURLを書き換えています。
実際にはサーバー側の設定によっては、リロード時に404が返ってしまうなどの問題があるので、サーバーのリライト設定が必要な場合が多いです。
しかし、最小構成としてのイメージはつかめるのではないでしょうか。
React Routerを使った画面遷移
SPAを実装するうえで、もっと便利な方法としてReact Routerを利用する例を見てみましょう。
Reactを使うときは、ルーティングだけにとどまらず、コンポーネント設計や状態管理なども絡んできます。
ここではあくまで「画面遷移」の部分にフォーカスして、React Routerの基本的な書き方を取り上げます。
React Routerの導入
React Routerは、React用のルーティングライブラリです。
ページ全体の再読み込みなしにURLを切り替えたり、指定されたパスに応じてコンポーネントを表示したりできます。
アプリの構成としては、ざっくり以下のような流れで画面遷移が実現されています。
BrowserRouter
でラップしたルート全体の設定Route
コンポーネントでパスと表示コンポーネントを紐付け- 遷移先を示すリンク(
Link
コンポーネントなど)をクリックするとURLが変わる history.pushState
を内包した仕組みによってリロードなしの画面切り替え
React Routerのサンプルコード
以下に簡単な例を示します。
import React from "react"; import { BrowserRouter, Routes, Route, Link } from "react-router-dom"; function Home() { return <h2>ホーム画面</h2>; } function About() { return <h2>アバウトページ</h2>; } function App() { return ( <BrowserRouter> <nav> <Link to="/">Home</Link> <Link to="/about">About</Link> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </BrowserRouter> ); } export default App;
上記のように、リンクをクリックするとURLが書き換わりますが、ブラウザはリロードしません。
その代わり、React Routerが内部でhistory APIを使用してURLとコンポーネントを結びつけているため、表示内容が動的に差し替えられます。
これによって、ユーザーが途切れずにサイトを利用できる感覚を得られるのです。
遷移時に考慮すべきポイント
画面遷移を実装するとき、以下のポイントも押さえておくと実務で役立ちます。
遷移後の状態管理
シングルページの文脈では、現在どの画面が表示されているのか、どんなデータを持っているのかなど、状態管理が複雑になりやすいです。
フレームワーク側の仕組み(ReactならReduxなど、VueならPiniaなど)を活用して、状態と画面表示をしっかり紐付けておくと混乱が少なくなります。
画面遷移とパフォーマンス
リロードを伴う方法でも、ページ数が多いプロジェクトだと、サーバーへ都度リクエストが飛んでしまうため、遷移に時間がかかる場合があります。
SPAライクな実装でも、コンポーネントを無理やり詰め込みすぎると、初回ロードが重くなる恐れがあります。
どちらを選ぶかは状況次第で、UIや動作が「サクサク」することとのバランスを考慮する必要があるでしょう。
SEOや検索エンジンのクローラ
通常、SPAはページをリロードしない分、検索エンジンがどこまでコンテンツを正しく認識できるかが課題になることがあります。
最近は検索エンジン側の対応が進んでいるとはいえ、ブラウザでレンダリングしなければ内容が出てこないページはクローラが十分に読み取れない可能性があります。
もし検索エンジンからの流入を大切にしたい場合は、 SSR (Server-Side Rendering) なども検討するのが望ましいかもしれません。
実務でのサンプルシナリオ:ログイン後のダッシュボード遷移
ここでは、よくあるシナリオとして「ログイン後にユーザーダッシュボードへ遷移する」という場面を例に考えてみましょう。
ログイン画面からのリダイレクト
ユーザーがログインフォームに情報を入力し、サーバー側で認証が成功したら、次のページへ進ませます。
シンプルな実装なら、サーバーから「成功」のレスポンスが返った後、クライアント側で location.href = "/dashboard"
とするだけです。
このように「リロードして別のページに行く」形式は、セキュリティ的に悪いわけではありません。
ただし、その後のダッシュボード画面もさらに細かいメニュー遷移を必要とする場合は、SPAっぽい構成のほうが使いやすいかもしれません。
SPA構成でのダッシュボード切り替え
もしReact Routerを使っているなら、ログインに成功した後は navigate("/dashboard")
のようにして画面を切り替えます。
バックエンドからのトークン確認が必要な場合は、リロードなしでもAjaxリクエストやCookieを活用するなどの工夫が求められます。
また、ログアウトを押したときには location.replace("/login")
を使って戻れないようにしたい、というパターンもあるでしょう。
業務システムの要件と併せて、どのメソッドやライブラリを使うか選んでみてください。
イベントハンドラを適切に管理する
画面遷移を繰り返すと、場合によっては複数のイベントハンドラが重複登録されるなどの不具合が起こることがあります。
たとえばSPAで画面のDOMを破棄して再生成するたびに、新しいイベントリスナーが追加され続けてしまうケースです。
DOM要素のライフサイクルやコンポーネントのマウント・アンマウントを意識して、イベントを適切に解除(removeEventListener)する仕組みを整えましょう。
フレームワークを使うと、コンポーネントが破棄されるときに自動的にリスナーを外してくれることがありますが、慣れないうちは予期せぬ不具合に悩まされるかもしれません。
モバイル端末での画面遷移
スマートフォンでブラウザ閲覧するとき、ページ遷移の挙動はPCと異なる点があります。
- タッチイベント(
touchstart
/touchend
)の扱い - モバイルブラウザ固有の表示領域や戻るボタン挙動
またSPA特有の画面遷移では、モバイル側で画面がリロードされないため、タスクキルしたあとに再度開いた場合に、どの画面が表示されるべきか混乱することもあるでしょう。
これらを考慮した設計・実装が大事です。
エラー処理の考え方
画面遷移の途中でサーバーエラーやネットワーク障害が起きた場合は、ユーザーに何らかのエラー表示を行って、再試行を促すなどのインタラクションを用意する必要があるでしょう。
- 通常のリロード型遷移であれば、ブラウザがエラーページを表示する
- SPAの場合はAjaxリクエストでエラーを受け取るので、JavaScript側でエラー画面やダイアログを出す
このように、どのような構成を選択するかによってエラー時のハンドリング方針が変わります。
エラー処理が適切に行われないと、ユーザーが真っ白な画面で詰まってしまったり、更新ボタンを押しても再度同じエラーで止まったりします。 画面遷移に限らず、エラー時のフロー設計を考えておきましょう。
画面遷移をめぐるセキュリティ面の注意
画面遷移とセキュリティは一見すると無関係に思えるかもしれませんが、次のような視点が重要です。
遷移先のURLに機密情報を含めない
クエリ文字列にトークンなどを載せると、ブラウザの履歴やサーバーログに残ってしまう可能性があります。
権限のないユーザーが直接URLを叩くケースを想定する
SPAであっても、URLを手入力されたり、直接リンクを踏まれたりすると意図しない画面へアクセスされる可能性があります。
ログイン必須の画面に対するガード処理
React Routerなどでは「ルートガード」と呼ばれる仕組みを用いて、ログインしていないユーザーをログイン画面へリダイレクトするなどの対応を行います。
これらを実装しないと、不正アクセスの温床となってしまう恐れがあります。
ハッシュ(#)を使った画面遷移
少し古い手法ですが、URLの末尾に #
(ハッシュ)を用いて実質的にページを切り替える「ハッシュルーティング」があります。
/#/about
のように、ハッシュ記号の後にパスっぽい文字列を付けることで、ブラウザがページをリロードせずにハッシュ部分の変更を認識して、JavaScriptで画面を切り替える仕組みです。
onhashchange
イベントを使ってハッシュの変更を捕捉し、表示を差し替えるコードを書く例があります。
window.addEventListener("hashchange", () => { const hash = window.location.hash; // 例: "#/about" // ここでhashに応じてコンテンツ切り替え });
これはサーバー側の設定をあまりいじらなくても済む利点がありますが、URLが少し読みにくくなったり、検索エンジンによっては評価が分かれる可能性もあるかもしれません。
ページリロード vs. 動的切り替え:使い分けの目安
結局、リロードを伴う画面遷移と動的な画面遷移、どちらを選べばいいのでしょうか。
以下のような視点で考えてみると、判断の助けになります。
ユーザーにとって使いやすいか
頻繁に移動するならSPA的な構成が快適に感じられることが多いです。
開発や保守が複雑になりすぎないか
小規模サイトならリロード型でも十分簡単でわかりやすいかもしれません。
SEOをどれだけ重視するか
クローラが読み取りやすい構成を望むなら、SSRなどが選択肢に挙がります。
サーバーサイドのセットアップ状況
サーバーのリライト設定が難しい場合、ハッシュルーティングのほうが導入が簡単なケースもあります。
最終的にはサイトの目的や規模感、チームの技術スタックなどを考慮して、どの方式が最適か選ぶとよいでしょう。
画面遷移とユーザー操作の整合性
画面遷移の際には、ユーザーの操作タイミングとUIの変化が噛み合っているかを常に意識します。
たとえば、ボタンをクリックしても何も表示が変わらない一瞬があると、ユーザーは「壊れた?」と混乱するかもしれません。
ローディング表示
サーバーとの通信が必要な場合は、ローディングインジケータを表示するなどしてユーザーに「処理中」であることを伝える。
アニメーションやトランジション
SPA的な画面切り替えをさらにわかりやすくするために、スライドやフェードを加える。
エラー時の明確なフィードバック
先ほど述べたように、失敗した場合は分かりやすいメッセージを出す。
こうした小さな工夫が、最終的なユーザー体験の質を大きく左右します。
シングルページと複数ページのハイブリッド構成
大規模なウェブサイトでは、完全にSPAにするのではなく、一部のページは通常のリロード型、特定のダッシュボードや管理画面だけSPAといった構成が取られる場合もあります。
- ホームページや記事一覧など、検索エンジンからの流入が重要でリロード型でも問題ない部分
- 会員専用ダッシュボードなど、ユーザーが連続操作を行う部分
こうして適材適所で使い分けることで、開発コストやSEO、パフォーマンスなどのバランスを取りやすくなります。
ライブラリ活用:Vue RouterやAngular Router
React以外のフレームワークでも、VueならVue Router、AngularならAngular Routerといった具合に、公式または準公式のルーティングソリューションが用意されています。
機能としてはReact Routerと同様、history APIを内部でラップしており、ルート設定やパラメータ管理、ガード機能などが揃っています。
どのフレームワークでも「URLと表示コンテンツの紐付け」「リロードなしでの画面切り替え」「ブラウザ履歴の扱い方」という大枠は変わらないので、実務でどれか一つを学んでおくと、他のフレームワークに移行しても応用しやすいかもしれません。
開発環境でのルーティング設定
SPAを扱う際、ローカルホストなどの開発環境では簡単にテストできる反面、本番のサーバーにデプロイすると、/about
に直接アクセスしたときに404エラーが返ってしまう問題に遭遇しがちです。
これは、サーバーが実際に /about
という物理パス(ファイル)を探しに行って見つからないからです。
SPAの場合は、サーバー側でどのURLにアクセスされても index.html
にリダイレクトし、JavaScriptにルーティングを任せる設定をすることが多いでしょう。
.htaccess や NGINXの設定 などで、適切にリライトを行う必要がある点に注意してください。
画面遷移とアクセシビリティ
JavaScriptによる画面切り替えが激しいサイトでは、スクリーンリーダーなどの支援技術でどのように読み上げられるかを意識する必要があります。
ページがリロードされない場合、ユーザーが次にどのコンテンツを読めばいいのか理解しづらくなるケースがあるからです。
- 遷移時にフォーカスを移動させる
- 遷移時に適切な見出しやテキストを表示して、変更内容を案内する
こうしたアクセシビリティ対応があると、より多くのユーザーにとって利用しやすいサイトになります。
画面遷移に関するよくある落とし穴
初心者の方がハマりやすいポイントをまとめておきます。
location.replace
を使い、戻るボタンが効かなくなって混乱する
「なぜ戻れないのか」がわからない場合があります。使いどころを明確にしましょう。
SPAでURLを切り替えてもサーバー側の設定をしていないため、リロードすると404になる
ローカルで動作確認しているときは問題なくても、本番環境で思わぬエラーが出ることがあります。
popstateイベントを見落として、戻るボタンを押したときに画面が更新されない
手動でstateを管理しているSPAでは特に要注意です。
ハッシュルーティングでページデザインを作り込んだが、SEOに影響があった
すべてが悪いわけではありませんが、状況によっては検索エンジンの評価が変わる可能性があります。
まとめ
画面遷移は、ウェブ開発において非常によく使う機能です。
JavaScriptで実現する方法はいくつかありますが、大きく分けると「リロードを伴う伝統的な方法」と「リロードなしに切り替えるSPA方式」が存在します。
location.href
やlocation.replace()
は簡単に実装できる- SPA的な遷移では、history APIやフレームワークのルーターを使ってURLと表示を分離して管理する
- 実務ではSEO、セキュリティ、アクセシビリティ、開発コストなどを踏まえて手法を選ぶ
初心者の皆さんが最初に学習するなら、まずは location.href
や location.replace()
で画面を切り替える基本を押さえるのがおすすめです。
そのうえで、より高度なUIが必要になったらSPAやReact Routerなどのルーティングライブラリに進むと、段階的に理解しやすいでしょう。
画面遷移はウェブアプリを作るうえで欠かせない重要な概念ですので、少しずつコード例を試しながら、自分のプロジェクトに合った方法を見極めてみてください。