ルート変更を監視する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 の違い)

推薦する

国内SNSのホームページを比較・分析して得た経験をみんなで共有(写真)

この記事では、ソーシャル ウェブサイトのホームページを比較分析することで洞察を得て、ソーシャル ウェ...

階段を転がす特殊効果を実現する JavaScript (jQuery 実装)

皆さんもJDを使ったことがあると思います。ホームページには非常によく見られる機能があります。階段の特...

Web 開発 js 文字列連結プレースホルダーと conlose オブジェクト API の詳細な説明

目次プレースホルダーの置き換えコンソール印刷テーブル()ログ、情報、警告、エラーグループ()、グルー...

特定のシンボルで複数の行と列に分割するMySQLの例

一部の障害コード テーブルでは、履歴またはパフォーマンス上の理由から、次の設計パターンが使用されます...

関数の分類の詳細な説明とJavascriptでのこのポイントの例

JS で関数を定義する 3 つの方法例を挙げて説明しましょう。 <スクリプト> //メソ...

Vueのハッシュジャンプ原理の詳細な説明

目次ハッシュと履歴の違いハッシュ履歴getCurrentLocation の実装setupListe...

Navicatを使ってMySQLを操作する方法

目次序文: 1. Navicatの紹介2. シンプルなチュートリアルの共有接続管理ライブラリテーブル...

WeChatアプレットのスクロールビューが左右の連動を実現

この記事では、WeChatアプレットのスクロールビューの左右連動を実現するための具体的なコードを参考...

JavaScript の setTimeout() の使用法の概要

目次1. はじめに2. setIntervalとsetTimeoutの違い3.タイムアウトを設定する...

モバイルウェブ画面適応(rem)

序文最近、フロントエンドの学習に関する以前のメモを整理したところ、モバイル Web 画面の適応 (r...

WindowsシステムでMySQLデータベースを完全にアンインストールして、MySQLを再インストールします

1. コントロールパネルで、MySQLのすべてのコンポーネントをアンインストールします。コントロール...

フロア効果を実現するためのJavaScript

この記事では、フロア効果を実現するためのJavaScriptの具体的なコードを参考までに紹介します。...

WeChatミニプログラムはuni-appを通じて世界中に共有されます

実際の使用では、ミニプログラムを友人や友人サークルと共有する必要があることが多く、通常は一度に 1 ...

MySQLデータベースとテーブルシャーディングの概要

プロジェクトの開発中に、データベースのデータがどんどん大きくなり、その結果、1 つのテーブルにデータ...

MAC 上の MySQL の初期パスワードを忘れた場合の対処方法

MACでMySQLの初期パスワードを忘れた問題を解決する方法を参考までに共有します。具体的な内容は次...