独自のネイティブ JavaScript ルーターを作成する方法

独自のネイティブ JavaScript ルーターを作成する方法

序文

ルーティングを考えるとき、通常は React のようなライブラリを思い浮かべます。しかし実際には、これらのライブラリとフレームワークは依然としてバニラ JavaScript を使用しています。では、どうすればこれを達成できるのでしょうか?

この「JavaScript ルーティング チュートリアル」が、ネイティブ js で独自のルーターを作成する方法を理解するのに役立つことを願っています。

導入

さまざまな理由で独自のルーティングを作成したいという人によく出会います。この記事を読んでいるということは、あなたもその一人かもしれません!

最も重要なのは、vanillajsrouter を使用するとフレームワークへの依存が減ることです。

実装に関係するすべての部分を理解していれば、Vanilla JavaScript で独自のルーティングを作成するのは比較的簡単です。

独自の JS ルーターを作成するときに知っておくべき重要な点は次のとおりです。

1. ネイティブ JS ルーティングの鍵となるのは location.pathname プロパティです。

2. .pathname の変更に応じて「popstate」イベントをリッスンします。これは、ブラウザのアドレス バーに新しい URL が入力されるたびに発生しますが、ページを更新するのではなく、新しいコンテンツを読み込んでビューを更新するだけです。

3. ルートをroutes[]配列に保存することを選択できます。

4. URL を解析するには、JavaScript 正規表現 ( RegEx ) を使用する必要があります。

5. ルーティングをネイティブ ブラウザ アーキテクチャに統合する場合は、履歴と history.pushState (JavaScript の History API) の基本的な理解が不可欠です。

まず、History API を扱います。

JavaScript 履歴 API

JavaScript History API について言及していない、標準的な JS ルーターのチュートリアルをたくさん見てきました。それは残念なことです。ブラウザの「戻る」ボタンと「進む」ボタンをクリックすると、閲覧履歴内の URL に移動することになるからです。 History API がなければ、ルーティングについて話す方法はありません。

1.history.back() は history.go(-1) と同じで、ユーザーがブラウザの [戻る] ボタンをクリックしたときと同じです。どちらの方法でも同じ効果が得られます。

2. ユーザーがブラウザの「進む」ボタンを押すと、history.forward() が実行されます。これは history.go(1) と同じです。

3.go() は .back() メソッドや forward() メソッドと似ていますが、ブラウザの履歴スタック内で前進または後退するステップ数を指定できる点が異なります。 。

4. pushState() は新しい状態を History API にプッシュします。

5..length プロパティは、セッション履歴内の要素の数です。

6..state プロパティは、「popstate」イベントをリッスンせずに状態を見つけるために使用されます。

独自のネイティブJSルーティングを実装する

History API に基づく Vanilla JS ルーティング設定

まず、URL スイッチャー (ページを更新せずに) を構築するために必要な最小限のコードを詳しく見て、次にそれがどのように動作するかを示す GIF を紹介します。

<html>
    <ヘッド>
        <title>こんにちは</title>
        <スクリプトタイプ = "モジュール">
            関数 select_tab(id) {
                // すべてのボタンから選択したクラスを削除します
                document.querySelectorAll(".route").forEach(item => item.classList.remove('selected'));
                // クリックした要素を選択する(視覚的に)
                document.querySelectorAll("#" + id).forEach(item => item.classList.add('selected'));
            }
            関数load_content(id) {
                // テキストを更新します「{id} のコンテンツを読み込んでいます...」
                // もちろん、ここでコンテンツの読み込みマジックを実行します
                // リソースを更新するために Fetch API を実行する必要があるかもしれません
                document.querySelector("#content").innerHTML = '/' + id + '...' のコンテンツを読み込んでいます。
            }
            関数push(イベント) {
                // クリックされたボックス、ボタン、またはリンクの id 属性を取得します
                id = event.target.id とします。
                // クリックしたボタン/タブ/ボックスを視覚的に選択する
                select_tab(id);
                // ウィンドウのタブのタイトルを更新
                ドキュメントのタイトル = id;
                // このタブ/ページのコンテンツを読み込む
                コンテンツをロードします。
                // 最後に状態の変更をアドレスバーにプッシュします
                window.history.pushState({id}, `${id}`, `/page/${id}`);
            }
            window.onload = イベント => {
                // ボックスがクリックされたときに履歴push()イベントを追加します
                window["home"].addEventListener("click", イベント => push(イベント))
                window["about"].addEventListener("click", イベント => push(イベント))
                window["ギャラリー"].addEventListener("クリック", イベント => push(イベント))
                window["contact"].addEventListener("click", イベント => push(イベント))
                window["help"].addEventListener("click", イベント => push(イベント))
            }
            // PopStateEvent をリッスンします (戻るまたは進むボタンがクリックされます)
            window.addEventListener("popstate", イベント => {
                // 履歴状態IDを取得する
                stateId = event.state.id; とします。
                // クリックされた ID をコンソールに表示する (単なる楽しみのため)
                コンソールにログ出力します。
                // クリックしたボタン/タブ/ボックスを視覚的に選択する
                select_tab(状態ID);
                // このタブ/ページのコンテンツを読み込む
                コンテンツをロードします。
            });
        </スクリプト>
        <スタイル>
            * { /* グローバルフォント */
                フォントファミリー: Verdana;
                フォントサイズ: 18px;
            }
            #root { display: flex; flex-direction: row; }
            #content { display: flex;
                表示: ブロック;
                幅: 800ピクセル;
                高さ: 250px;
                /* 垂直中央揃えのテキスト */
                行の高さ: 250px;
                境界線: 2px 実線 #555;
                マージン: 32px;
                テキスト配置: 中央;
            }
            .ルート{
                カーソル: ポインタ;
                コンテンツの中央揃え: 中央;
                幅: 150ピクセル;
                高さ: 50px;
                /* 垂直中央揃えのテキスト */
                行の高さ: 50px;
                位置: 相対的;
                境界線: 2px 実線 #555;
                背景: 白;
                テキスト配置: 中央;
                マージン: 16px;
            }
            .route.selected { 背景: 黄色; }
        </スタイル>
    </head>

    <本文>

        <セクション id = "ルート">
            <section class = "route" id = "home">/home</section>
            <section class = "route" id = "about">/about</section>
            <section class = "route" id = "gallery">/ギャラリー</section>
            <section class = "route" id = "contact">/contact</section>
            <section class = "route" id = "help">/help</section>
        </セクション>

        <main id = "content">コンテンツを読み込んでいます...</main>
    
    </本文>

</html>

コアとなるのは、window.history.pushState({id}, ${id}, /page/${id}); を呼び出すことです。

最初のパラメータは状態の一意の ID、2 番目は「タブ タイトル」のテキスト、3 番目のパラメータはアドレス バーに表示するパスです。これにより、ブラウザはページを再読み込みせずに URL を変更できるようになります。

結果。これで、ボタンをクリックするたびに、ブラウザのアドレスバーの URL が実際に変更されます。コンテンツボックスも更新されます。

ネイティブ JS ルーターが動作可能になりました。ボタンがクリックされるたびに history.pushState がトリガーされることに注意してください。要素の id 属性に保存されているクリックされた要素の id (home、about、gallery など) を渡すだけです。これらは、移動先の実際のページに対応している必要があります。もちろん、これがページ名を保存する唯一の方法ではありません。array[] やその他の方法を使用することもできます。この例ではこのように実行されます。

もちろん、その場所のレイアウトとリソースもサーバーから読み込む必要があります。それはあなたのプログラムによって異なります。それは何でもあり得ます。

「戻る」ボタンと「進む」ボタンを機能させる

history.pushState を使用すると、「戻る」ボタンと「進む」ボタンが自動的に前の状態または次の状態に移動します。これを行うと、popstate イベントが生成されます。これは、ビューを再度更新する必要がある部分です。 (最初はボタンをクリックしたときです。)

ただし、イベントにはクリックの ID が含まれるため、「戻る」または「進む」がクリックされたときにビューを更新してコンテンツを再読み込みするのは簡単です。

ここでは react や vue を使用していないため、ソース コードでは load_content が DOM 内で直接ビューを更新する役割を担います。この領域には、API によって読み込まれたコンテンツが表示される場合があります。これは単なる「フロントエンド」の例なので、あまり詳しくはお見せできません。しかし、クライアント側ではそのように動作します。

サーバー側ルーティング負荷を初期化する

すべてをまとめるには、もう 1 つの手順が必要です。私の例では、router.html のみが使用されました。このルートを PWA に初めて読み込むときは、アドレス バーに /page/home を直接入力した場合に機能することを確認する必要があります。

これまでのところ、フロントエンドからのルーターのアドレスのみを変更しました。ルーターのボタンに表示される URL に移動するたびに、その URL が実際にはサーバーから個別に読み込まれると想定します。

したがって、/page/about ルーターとページがアプリケーションのルート ビューに読み込まれるようにするのはユーザーの責任です。 「現在」ボタンも強調表示されます。

実装すると、ルーティングが完了します。 #content 要素内のコンテンツをどのようにリロードするかは、完全にユーザーとバックエンドの設計次第です。

上記は、独自のネイティブ JavaScript ルーターを作成する方法の詳細です。ネイティブ JavaScript ルーターの作成の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • メンテナンス可能なオブジェクト指向 JavaScript コードの作成
  • JavaScript を使用してメンテナンス可能なスライドショー コードを作成する
  • JavaScriptのURLオブジェクトとは何かについて話しましょう
  • JavaScript における正規表現の実際的な応用の詳細な説明
  • JavaScript で配列遅延評価ライブラリを実装する方法
  • Javascript実践におけるコマンドモードの詳しい説明
  • JavaScript でアルゴリズムの複雑さを学ぶ方法
  • いくつかの面接の質問を使ってJavaScriptの実行メカニズムを調べる
  • メンテナンス可能なJSコードの書き方を教えます

<<:  Windows 64 ビット版 MySQL 5.7 以降の解凍パッケージにデータディレクトリと my-default.ini がなく、サービスが起動できない問題の簡単な解決方法 (問題概要)

>>:  LinuxサーバにおけるNginxとApacheの共存の実装方法の分析

推薦する

CSS で要素を垂直方向に中央揃えする 7 つの方法

【1】中央の要素の幅と高さを知る絶対値 + 負のマージンコードの実装 .wrapBox5{ 幅: 3...

WordPress実験を実装するための3つの仮想マシンのKVM展開の詳細説明

1. KVM の概要カーネルベースの仮想マシンの略称は、Linux 2.6.20 以降のすべての主要...

CSS を使用して fullpage.js のフルスクリーン スクロール効果を実装するサンプル コード

最近 CSS を勉強していたとき、 2 つの CSS プロパティだけを使用して全画面スクロール効果を...

広告を閉じるための JavaScript カウントダウン

広告を閉じるまでのカウントダウンを実装するために JavaScript を使用するまだフロントエンド...

ホームページのデザインはウェブデザイナーのレベルを最もよく反映する

私がこれまで携わってきた多くのプロジェクトでは、基本的に避けられない悪循環がありました。それは、ホー...

Apache ab同時負荷ストレステストの実装方法

腹筋コマンドの原則Apache の ab コマンドは、マルチスレッドの同時リクエストをシミュレートし...

MySQL マスタースレーブレプリケーションの原理からインストールと設定までを包括的に解説します。

マスタースレーブレプリケーションがなぜ必要なのでしょうか? 1. 複雑な業務システムでは、SQL 文...

3つの簡単な調整でMySQLを最適化する

私は熟練した DBA になるつもりはありませんが、MySQL を最適化するときは、いくつかの構成を調...

Xshellの一般的な問題と関連する設定の詳細な説明

この記事では、Xshell と関連する構成の一般的な問題について説明します。この記事の構成は、主に ...

JS を使用して配列内の要素の存在を 10 分で判断する

序文フロントエンド開発では、配列内に要素が存在するかどうかを判断する必要があることがよくあります。実...

Webpackを使用して複数ページのプログラムを構築するための実装手順

webpack を使用してシングルページのプログラムを構築することは非常に一般的ですが、実際の開発で...

MySQL で重複時間を削除して時間差を計算する実装

目次必要:ドライブ:アイデア:成し遂げる:個人的には、実際の開発ではストアド プロシージャの使用はお...

CSS 要素を表示および非表示にする 9 つの方法

Web ページの制作では、要素の表示と非表示は非常に一般的な要件です。この記事では、要素を表示したり...

Linuxコマンド履歴の調整方法の詳細な説明

Linux システムの bash history コマンドは、以前に実行したコマンドを記憶し、再入力...

dockerでマウントされたディレクトリが読み書きできない問題を解決する

次のコマンドを使用してコンテナを作成し、ローカルの /home/dock/Downloads ディレ...