ルート変更を監視するJavaScriptの詳細な説明

ルート変更を監視するJavaScriptの詳細な説明

フロントエンドでルーティング変更を実装する方法は主に2つあります。この2つの方法の最大の特徴は、リフレッシュ機能なしでURL切り替えを実装することです。

  1. ハッシュを変更して、window.onhashchange を使用してリッスンします。
  2. 履歴の変更により、ページをロードするための js 操作が実行されます。ただし、履歴はハッシュほど単純ではありません。ブラウザのいくつかの前後の操作 (history.back()、history.forward()、history.go() メソッドを使用して、ユーザーの履歴レコード内で前後にジャンプする) を除き、履歴の変更によって popstate イベントがアクティブにトリガーされるためです。PushState と replaceState は popstate イベントをトリガーしません。

歴史

主に歴史を理解するため

pushState() メソッド

これには、ステータス オブジェクト、タイトル (現在は無視されます)、(オプション) URL の 3 つのパラメータが必要です。それぞれについて詳しく説明しましょう。

状態オブジェクト — 状態オブジェクト状態は、pushState() を介して新しい履歴エントリを作成する JavaScript オブジェクトです。ユーザーが新しい状態に移動するたびに、popstate イベントが発生し、イベントの状態プロパティには履歴エントリの状態オブジェクトのコピーが含まれます。 状態オブジェクトは、シリアル化できるものであれば何でも構いません。その理由は、Firefox はユーザーがブラウザを再起動したときに使用するために状態オブジェクトをユーザーのディスクに保存し、状態オブジェクトのシリアル化された表現に 640k のサイズ制限を設定しているためです。シリアル化後に 640k を超える状態オブジェクトを pushState() メソッドに渡すと、メソッドは例外をスローします。より多くのスペースが必要な場合は、sessionStorage と localStorage を使用することをお勧めします。

title — Firefox は現在このパラメータを無視しますが、将来的には使用される可能性があります。ここで空の文字列を渡すと、このメソッドが将来変更されても安全になります。オプションで、リダイレクト先の状態の短いタイトルを渡すこともできます。

URL — このパラメータは、新しい履歴 URL レコードを定義します。ブラウザは pushState() を呼び出した直後に URL をロードするのではなく、ユーザーがブラウザを再度開いたときなど、後で URL をロードする場合があることに注意してください (リソースはロードされませんが、変更をリッスンしてビューを変更することができ、ページを更新せずに単一ページ ルーティングを実装する方法になります)。新しい URL は絶対パスである必要はありません。新しい URL が相対パスの場合、現在の URL を基準として扱われます。新しい URL は現在の URL と同じオリジン (同一オリジン ポリシー) である必要があります。そうでない場合、pushState() は例外をスローします。このパラメータはオプションであり、デフォルトでは現在の URL になります。

ある意味では、pushState() を呼び出すことは、現在のページに新しい履歴レコードを作成してアクティブ化する点で、window.location = "#foo" を設定することに似ています。しかし、pushState() には次のような利点があります。

新しい URL は、現在の URL と同じオリジンを持つ任意の URL にすることができます。逆に、ハッシュを変更する場合、window.location の設定は同じドキュメントのみになります。
URL を変更したくない場合は、変更しないでください。逆に、window.location = "#foo"; を設定すると、現在のハッシュが #foo でない場合にのみ新しい履歴項目が作成されます。
新しい履歴項目に任意のデータを関連付けることができます。ハッシュベースのアプローチでは、関連するすべてのデータを短い文字列にエンコードします。
その後、ヘッダーがブラウザによって使用される場合、このデータは使用できます (ハッシュは使用できません)。

新しい URL が古い URL とハッシュのみが異なる場合でも、pushState() は hashchange イベントをトリガーしないことに注意してください。

pushState() の使用シナリオ

履歴は更新せずにURLまたはURLパラメータを変更できます

window.history.replaceState('', '', `${window.location.origin}${window.location.pathname}type=a`);

replaceState() メソッド

history.replaceState() の使用は history.pushState() と非常に似ていますが、違いは replaceState() が新しい履歴項目を作成するのではなく、現在の履歴項目を変更することです。 ただし、これによって、グローバル ブラウザ履歴に新しい履歴項目が作成されなくなるわけではないことに注意してください。
作る

ポップステートイベント

window.onpopstate を使用して戻りイベントをリッスンする

window.onpopstate = funcRef;

funcRef : (イベント:{状態:任意})=>void

アクティブな履歴レコードが変更されるたびに、対応するウィンドウ オブジェクト (window.onpopstate) で popstate イベントがトリガーされます。現在アクティブな履歴エントリが history.pushState() メソッドによって作成されたか、または history.replaceState() メソッドによって変更された場合、popstate イベント オブジェクトの状態プロパティには、履歴エントリの状態オブジェクトのコピーが含まれます。

**知らせ:

  1. history.pushState() または history.replaceState() を呼び出しても、popstate イベントはトリガーされません。popstate イベントは、戻るボタンまたは進むボタンのクリック (または JavaScript で history.back()、history.forward()、history.go() メソッドの呼び出し) などの特定のブラウザー アクションによってのみトリガーされます。さらに、a タグのアンカーによってもイベントがトリガーされます。
  2. Web ページが読み込まれると、popstate イベントがトリガーされるかどうかについては、ブラウザごとに動作が異なります。Chrome と Safari は popstate イベントをトリガーしますが、Firefox はトリガーしません。

pushState と replaceState を監視する方法は?

サブスクリプション公開モードを通じて、これを自分で実装することができます。まず、サブスクリプション公開モードであるDepとWatchを使用します。これは、実際にはVueソースコードdepとwantcher間の実装方法の簡略化されたバージョンです。

class Dep { // サブスクリプションプールコンストラクター(名前){
        this.id = new Date() //ここでは、サブスクリプションプールのIDとしてタイムスタンプを使用します
        this.subs = [] //このイベントでサブスクライブされたオブジェクトのコレクション}
    defined(){ // サブスクライバーを追加します Dep.watch.add(this);
    }
    notification() { // 購読者に変更を通知する this.subs.forEach((e, i) => {
            if(typeof e.update === 'function'){
                試す {
                   e.update.apply(e) // サブスクライバー更新関数をトリガーする} catch(err){
                    コンソール.warr(エラー)
                }
            }
        })
    }
    
}
Dep.watch = null;

クラスウォッチ{
    コンストラクタ(名前,関数){
        this.name = name; //サブスクリプションメッセージの名前 this.id = new Date(); //ここでは、タイムスタンプをサブスクライバーのIDとして使用します
        this.callBack = fn; //サブスクリプションメッセージが送信され変更されると、サブスクライバーによってコールバック関数が実行されます}
    add(dep) { // サブスクライバーを dep サブスクリプション プールに追加します dep.subs.push(this);
    }
    update() { // サブスクライバーメソッドを更新 var cb = this.callBack; // 関数内で呼び出される this を変更しないように割り当てる
        cb(この名前);          
    }
}

historyメソッドを再実装し、addHistoryListenerメソッドを追加します。

const addHistoryMethod = (関数(){
 var historyDe​​p = new Dep() // サブスクリプションプールを作成する return function (name) {
  if(name==='履歴変更'){
   var event = new Watch(name,fn);
   依存関係ウォッチ = evnet;
   historyDe​​p.defind(); // サブスクライバーを追加 Dep.watch = null;
  }それ以外の場合(name==='pushState'||name==='replaceState'){
   var メソッド = history[名前];
   関数()を返す{
    method.apply(履歴、引数)
    履歴を通知します。
   }
  }
 }
})()
window.addHistoryListener = addHistoryMethod('historyChange')
history.pushState = addHistoryMethod('pushState');
history.replaceState = addHistoryMethod('replaceState');

カプセル化は成功しました。テスト使用例

window.addHistoryListener('履歴',function(){
 console.log('ウィンドウ履歴が変更されました')
})
window.addHistoryListener('履歴',function(){
 console.log('ウィンドウ履歴が変更されました。私もそれを聞きました') // 複数のリスニングイベントをバインドできます console.log(history.state)
})
history.pushState({foo:bar}, 'title', '/car')

現在のステータスを取得する

ページが読み込まれると、null 以外の状態オブジェクトが存在する場合があります。これは、たとえば、ページが状態オブジェクトを(pushState() または replaceState() メソッドを介して)設定し、その後ユーザーがブラウザを再起動した場合などに発生する可能性があります。その後、ページがリロードされると、ページは onload イベントを受信しますが、popstate イベントは受信しません。ただし、history.state プロパティを読み取ると、popstate がトリガーされた場合と同じ状態オブジェクトが取得されます。

popstate イベントを待たずに現在の履歴項目の状態オブジェクトを読み取ることができます。次のように history.state プロパティを使用します。

現在の状態を history.state とします。

対比

プッシュステート状態を置き換える
現在のページで新しい履歴レコードが作成され、アクティブ化されます。戻るボタンをクリックすると、前の URL に戻ります。現在の履歴が変更されます。戻るボタンを押すと、変更された URL はスキップされます。

要約する

履歴は非更新ルーティングを実装する方法であり、安定したシステムエクスペリエンスを確保するための単一ページ開発に特に適しています。ただし、履歴は pushState と replaceState の動作を監視せず、go、back、forward の動作のみを監視します。ただし、サブスクリプション公開モードを使用し、Dep と Watch を使用し、pushState および replaceState イベントを再パッケージ化し、呼び出し後に通知メソッドを自動的にトリガーし、addHistoryListener メソッドを追加してリスニング コールバック (サブスクライバー) を追加することができます。

これで、JavaScript を使用してルート変更を監視する方法についての記事は終了です。JavaScript を使用してルート変更を監視する方法の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • vue.js でルートの変更を監視するために watch を使用する方法
  • AngularJS でルートの変更を監視する方法
  • AngularJS はルート変更をリッスンします サンプルコード

<<:  Dockerでプロジェクトを実行する方法

>>:  MySQL テーブル削除操作の実装 (delete、truncate、drop の違い)

推薦する

Vue で配列をクリアするいくつかの方法 (要約)

目次1. はじめに2. データを消去するいくつかの方法2.1 ref() の使用2.2 スライスの使...

HTMLの基礎を徹底解説(第1部)

1. WEBを理解するWeb ページは主にテキスト、画像、ハイパーリンクなどの要素で構成されていま...

jQueryはショッピングカート機能を実装します

この記事の例では、ショッピングカート機能を実装するためのjQueryの具体的なコードを参考までに共有...

HTML ユーザー登録ページ設定ソースコード

上記の Web ページをデザインします。 <!DOCTYPE html> <htm...

WindowsはVMwareを使用してLinux仮想マシンを作成し、CentOS7.2オペレーティングシステムをインストールします。

目次1. ウィザードに従って仮想マシンを作成します2. オペレーティングシステムをインストールします...

MySQLのストレージエンジンの詳細な説明

MySQL ストレージ エンジンの概要ストレージ エンジンとは何ですか? MySQL のデータは、さ...

Ubuntu環境でのPHP関連のパスと変更方法

Ubuntu環境におけるPHP関連パスPHP パス /usr/bin/php phpize5 /us...

PHP で JSON バックスラッシュを削除する例

1. 「stripslashes($_POST['json']);」メソッドを使用し...

ウェブページのテーブルの境界線を設定する方法

<br />前回は、Web テーブルにセルの線を設定する方法を学びました。今日は、Web...

MySQLトランザクションとMySQLログの詳細な説明

取引特性1. アトミック性: トランザクションの開始後、すべての操作が完了するか、まったく実行されな...

JavaScript継承のさまざまな方法とメリット・デメリットを詳しく解説

目次1. プロトタイプチェーン継承2. コンストラクタの借用(古典的な継承) 3. 組み合わせ継承4...

練習と面接のための Linux シェル スクリプトのヒント 9 つを共有する

予防1) 先頭にインタープリターを追加します: #!/bin/bash 2) 構文のインデントに 4...

HTML 画像 img タグ_Powernode Java アカデミー

まとめプロジェクトの説明形式<img src="..."> H2+ ...

QQtabBar による CSS 命名仕様 BEM の詳細な紹介

QQtabBar の BEMまず、BEMとはどういう意味でしょうか? BEM は、ブロック、要素、修...

Vueは適切なスライドアウトレイヤーアニメーションを実装します

この記事では、適切なスライドアウトレイヤーアニメーションを実装するためのVueの具体的なコードを例と...