フロントエンドルーティングHashとHistoryモード


SPAについて
現代のフロントエンドプロジェクトの多くは単一ページWebアプリケーション(SPA)であり、単一ページWebアプリケーションにおけるルーティングはその重要な一環である.SPAはsingle page webアプリケーションの略称で、単ページWebアプリケーションに訳されています.簡単に言えば、SPAはWEBプロジェクトでHTMLページが1つしかありません.ページのロードが完了すると、SPAはユーザーの操作によってページの再ロードやジャンプを行うことはありません.代わりに,JSを用いてHTMLの内容を動的に変換し,複数のビュー間ジャンプをシミュレートする.
ぜんどうろ
簡単に言えば、HTMLページが1つしかなく、ユーザーと対話している間にページをリフレッシュしたりジャンプしたりしないことを保証しながら、SPAの各ビューの表示形式に特殊なurlを一致させることです.この特殊なurlにより,リフレッシュ,前進,後退,SEOが実現される.次の2点を満たす必要があります.
  • urlを変更し、ブラウザがサーバのように要求を送信しないようにします.
  • urlの変化を傍受できる
  • ページをリフレッシュすることなくブラウザアドレスバーのURLアドレス
  • を動的に変更することができる.
    hashモードとhistoryモードは、上記の機能を実現するために使用されます.
    Hashモード
    urlの後ろに#を付けると、http://127.0.0.1:5500/ /hash.html#/page1というurlの後ろの#/page1がhash値になります.
  • hash値の変化は、ブラウザ像サーバの送信要求
  • を招くことはない.
  • location.hashはhash値
  • を取得することができる.
  • hashchangeはhash値が変化する呼び出しの関数
  • である.
    以上の3点に基づいてルーティングの例を書くことができます Document class RouterClass { constructor() { this.routes = {}; // cb this.currentUrl = ""; // hash cb window.addEventListener("load", () => this.render()); window.addEventListener("hashchange", () => this.render()); } /* */ static init() { window.Router = new RouterClass(); } /* */ route(path, cb) { this.routes[path] = cb || function() {}; } /* hash, cb */ render() { this.currentUrl = window.location.hash.slice(1) || "/"; this.routes[this.currentUrl](); } } RouterClass.init(); const ContentDom = document.querySelector(".content-div"); const changeContent = content => (ContentDom.innerHTML = content); Router.route("/", () => changeContent(" ")); Router.route("/page1", () => changeContent("page1 ")); Router.route("/page2", () => changeContent("page2 "));
    Historyモード
    Historyインタフェースでは、ブラウザのラベルページまたはフレームワークにアクセスしたセッション履歴を操作できます.次の2つの文章を参考にしてhistoryの説明をすることができます.https://css-tricks.com/using-the-html5-history-api/https://developer.mozilla.org/zh-CN/docs/Web/API/Historyこのモードで使用するapiについて説明します
    history基本api
  • history.go(n):ルーティングは数歩ジャンプし、nは2前に2ページジャンプし、-2後に2ページ
  • をジャンプする.
  • history.back():ルーティングバック、history.go(-1)に相当し、ユーザーはブラウザの左上隅のバックボタンをクリックしてこの方法
  • をシミュレートすることができる.
  • history.forward():ルーティング前進、history.go(1)に相当し、ユーザーはブラウザの左上隅の前進ボタンをクリックしてこの方法
  • をシミュレートすることができる.

  • pushState() history.pushState():ルーティング履歴を追加し、ドメイン間URLを設定するとエラーが表示されます.history.pushStateは、ブラウズ履歴に履歴を追加するために使用されますが、ジャンプはトリガーされません.この方法では、次の3つのパラメータが受け入れられます.state:指定されたWebサイトに関連するステータスオブジェクト.popstateイベントがトリガーされると、オブジェクトはコールバック関数に入力されます.このオブジェクトを必要としない場合は、ここに記入できます.null . title:新しいページのタイトルですが、すべてのブラウザは現在この値を無視しているので、ここに記入できます.null . url:新しいWebサイトは、現在のページと同じドメインにある必要があります.ブラウザのアドレスバーにこのURLが表示されます.
    Windowsのpopstateイベント
    アクティビティ履歴エントリが変更されるとpopstateイベントがトリガーされます.アクティブ化された履歴エントリがhistory.PushState()の呼び出しが作成されたか、history.replaceState()の呼び出しの影響popstateイベントのstateプロパティには、履歴エントリのステータスオブジェクトのコピーが含まれます.注意すべきはhistoryを呼び出すことです.义齿replaceState()はpopstateイベントをトリガーしません.ユーザーがブラウザのロールバックボタンをクリックしたり(Javascriptコードでhistory.back()を呼び出したり)ブラウザの動作をしている場合にのみ、イベントがトリガーされます. Document class RouterClass { constructor(path) { this.routes = {}; // cb history.replaceState({ path }, null, path); // this.routes[path] && this.routes[path](); window.addEventListener("popstate", e => {// console.log(e.state) const path = e.state && e.state.path; this.routes[path] && this.routes[path](); }); } /* */ static init() { window.Router = new RouterClass(location.pathname); } /* */ route(path, cb) { this.routes[path] = cb || function() {}; } /* , */ go(path) { history.pushState({ path }, null, path); console.log(history); this.routes[path] && this.routes[path](); } } RouterClass.init(); const ul = document.querySelector("ul"); const ContentDom = document.querySelector(".content-div"); const changeContent = content => (ContentDom.innerHTML = content); Router.route("/", () => changeContent(" ")); Router.route("/page1", () => changeContent("page1 ")); Router.route("/page2", () => changeContent("page2 ")); ul.addEventListener("click", e => { console.log(e.target.tagName); if (e.target.tagName === "A") { e.preventDefault(); Router.go(e.target.getAttribute("href")); } });
    HashモードとHistoryモードの比較
    Hashモードは、URLのHashを使用して完全なURLをシミュレートするため、URLが変更されるとページは再ロードされません.HistoryモードではURLが直接変更されるため、ルーティングジャンプ時にアドレス情報が失われ、ルーティングアドレスをリフレッシュまたは直接アクセスする際に静的リソースに一致しません.そのため、サーバにindexのジャンプなど、すべての状況をカバーする候補リソースを追加する情報を構成する必要がある.htmlなんて
    hashルーティングのメリットとデメリット
  • の利点
  • は簡単で、互換性が良い(ie8に互換性がある)
  • を実現する.
  • のほとんどのフロントエンドフレームワークは、hashに与えるルーティング実装
  • を提供する.
  • サーバ側での設定や開発は不要
  • は、リソースロードおよびajaxの要求を除く、他の要求
  • を開始しない.
  • の欠点
  • は、部分的にリダイレクトが必要な操作に対して、バックエンドがhashの部分的な内容を取得することができず、バックグラウンドがurlのデータを取得することができなくなり、典型的な例は、微信公衆番号のoauth検証
  • である.
  • サーバ側は、フロントエンドルーティング情報
  • を正確に追跡することができない.
  • アンカー機能を必要とする需要は、現在のルーティングメカニズムと衝突する
  • .

    History(browser)ルーティングのメリットとデメリット
  • の利点
  • は、リダイレクト中にurlのパラメータを失うことはありません.バックエンドはこのデータ
  • を取得できます.
  • のほとんどの前段フレームワークは、browserのルーティング実装
  • を提供する.
  • のバックエンドは、ルーティング情報
  • を正確に追跡することができる.
  • は、history.stateを用いる、現在のurlに対応する状態情報
  • を取得することができる.
  • の欠点
  • 互換性はhashルーティング(IE10のみ)
  • に及ばない.
  • は、html文書
  • を返すたびにバックエンドサポートを必要とする.

    参考記事
    インスタンスのソース:https://segmentfault.com/a/1190000018081475公式ドキュメント:https://developer.mozilla.org/en-US/docs/Web/API/History_APIメリットとデメリットの比較:https://juejin.im/post/5b5ec5...