1.需要
あなたは、フロントエンドのルーティングを実装する場合、どのように前方と後方のブラウザを達成するには?
最初のブログよりアドレス:GitHubに
2.問題
フロントエンドは、ランダム歴史ブラウザを閲覧し操作することができないように、まず、この主要なブラウザには、いくつかの制限が、あります。
- これは、前後にイベントリスナーを提供していません。
- 開発者は閲覧履歴を読み取ることができない、それはjsの閲覧履歴を読んでされていません。
- ユーザーが手動でアドレスを入力するか、URLを変更するために提供前後のブラウザを使用することができます。
だから、カスタムルーティングを実装するために、解決策はあるルートの歴史の自分の記録を維持するために、前方に区別するために、更新し、ロールバックします。
以下は、特定のメソッドについて説明します。
3.メソッド
私は1つのことであり、2つの方法があります知って増加して再度アレイを削除する他は、スタックLIFOの原理を利用。
3.1。最後に、アレイを追加および削除
変更イベントモニタルーティングなhashchangeことによって、まず、第1のイベント荷重を負荷したルーティングは、次のことを決定します。
- 閲覧履歴は、現在のルートの後ろに閲覧の履歴を削除するには、戻ったときに、背中、あるにURLが存在しています。
- とき前方urlは、配列現在のルート内でプッシュするために、進行中の歴史の中で存在していません。
- リフレッシュは、ルートの配列で何もしないときurlは、歴史の最後にリフレッシュされます。
さらに、ルーティングパスは、アプリケーションが同じ経路( - > B - 例えば、A> A)複数回発生することができるようにするため、同じ経路のインスタンスを区別するために各ルートにキー値を追加します。
注意:記録を復元することができた後、ユーザーがブラウザを更新するように、この歴史は、のsessionStorageに格納する必要があります。
次のように著者の前に実施ネイティブJSで実装軽量ルーティングは、この方法は、特定のコードを実装しています。
// 路由构造函数
function Router() {
this.routes = {}; //保存注册的所有路由
this.routerViewId = "#routerView"; // 路由挂载点
this.stackPages = true; // 多级页面缓存
this.history = []; // 路由历史
}
Router.prototype = {
init: function(config) {
var self = this;
//页面首次加载 匹配路由
window.addEventListener('load', function(event) {
// console.log('load', event);
self.historyChange(event)
}, false)
//路由切换
window.addEventListener('hashchange', function(event) {
// console.log('hashchange', event);
self.historyChange(event)
}, false)
},
// 路由历史纪录变化
historyChange: function(event) {
var currentHash = util.getParamsUrl();
var nameStr = "router-history"
this.history = window.sessionStorage[nameStr] ? JSON.parse(window.sessionStorage[nameStr]) : []
var back = false, // 后退
refresh = false, // 刷新
forward = false, // 前进
index = 0,
len = this.history.length;
// 比较当前路由的状态,得出是后退、前进、刷新的状态。
for (var i = 0; i < len; i++) {
var h = this.history[i];
if (h.hash === currentHash.path && h.key === currentHash.query.key) {
index = i
if (i === len - 1) {
refresh = true
} else {
back = true
}
break;
} else {
forward = true
}
}
if (back) {
// 后退,把历史纪录的最后一项删除
this.historyFlag = 'back'
this.history.length = index + 1
} else if (refresh) {
// 刷新,不做其他操作
this.historyFlag = 'refresh'
} else {
// 前进,添加一条历史纪录
this.historyFlag = 'forward'
var item = {
key: currentHash.query.key,
hash: currentHash.path,
query: currentHash.query
}
this.history.push(item)
}
// 如果不需要页面缓存功能,每次都是刷新操作
if (!this.stackPages) {
this.historyFlag = 'forward'
}
window.sessionStorage[nameStr] = JSON.stringify(this.history)
},
}
上記のコードは、この記事の唯一の関連コンテンツが一覧表示されます、の完全な内容を参照してください軽量JSネイティブルーティングを達成するために、およびページ間をジャンプするキャッシュ機能があります。
原則として後に高度な後発の3.2を使用先入れ先出しスタック、
第二の方法について話をする前に、最初は原則として後に高度なスタックとファーストアウト後発の定義を理解します。
3.2.1定義
スタック機能:アウト後に進んだ人は、最初に出て、中の最後。
例えば、生活の説明:積み重ねられたプレートのスタックです。私たちは、通常、皿を下から上に一つずつ置かれたときに置いて、時間がかかる、我々は中間の任意から抽出することができないから、1つのずつ順番に降ろされています。
機能の後に高度な先入れ先出しスタック後発、ので、それだけで、インサートの一端をスタックし、操作を削除することができます。これはまた、第一の原則と方法同じ目的を持っています。
以下のJavaScriptを使用して、スタックの順序を実装します:
// 基于数组实现的顺序栈
class ArrayStack {
constructor(n) {
this.items = []; // 数组
this.count = 0; // 栈中元素个数
this.n = n; // 栈的大小
}
// 入栈操作
push(item) {
// 数组空间不够了,直接返回 false,入栈失败。
if (this.count === this.n) return false;
// 将 item 放到下标为 count 的位置,并且 count 加一
this.items[this.count] = item;
++this.count;
return true;
}
// 出栈操作
pop() {
// 栈为空,则直接返回 null
if (this.count == 0) return null;
// 返回下标为 count-1 的数组元素,并且栈中元素个数 count 减一
let tmp = items[this.count-1];
--this.count;
return tmp;
}
}
実際には、JavaScriptは、アレイの拡張は自動的に行われ、スタック・サイズをnに指定することができない配列のサイズを指定する必要はありません。
3.2.2アプリケーション
古典的なアプリケーションスタック:関数呼び出しスタック
各スレッドのオペレーティングシステムは、このメモリは、関数呼び出しの一時変数を記憶するために使用される、そのような構造の「スタック」に編成され、別々のメモリ空間を割り当てられます。各機能に入る、それが呼び出された関数の戻り、スタックのスタックフレームに対応する機能の実行が完了した後、スタック上のスタックフレームとして一時変数であろう。あなたのより良い理解を与えるために、我々は、このコードの実行を見てください。
function add(x, y) {
let sum = 0;
sum = x + y;
return sum;
}
function main() {
let a = 1;
let ret = 0;
let res = 0;
ret = add(3, 5);
res = a + ret;
console.log("res: ", res);
reuturn 0;
}
main();
上記のコードは、主な機能は、加算、順番に追加機能を呼び出す主な機能、高度なスタックの最初の呼び出しを実行することで、また非常に簡単です。
次のように実装プロセスは以下のとおりです。
前方3.2.3ブラウザの実装、後方
第二の方法は、2つの前方と後方のスタック機能を備えたブラウザの実装。
我々は2つのスタック、XとYを使用して、我々はスタックY.に入れているあなたが最初に、スタックXにプッシュ左折ページを閲覧[戻る]ボタンをクリックすると、その後、スタックXからのスタック、およびデータスタックを回し入れ 我々は前進ボタンをクリックすると、我々はスタックからYデータを消し、スタックはXに配置され スタックXは、データが存在しない場合は、以下のページが戻って閲覧し続けることはできないことを示しています。スタックYデータがないが、それが存在することを示しているときに何ページには、前方参照するには、ボタンをクリックすることはできません。
たとえば、あなたは、B、3ページC、我々は、Bに向けるシーケンスを参照して、cがスタック、この時、データの2つのスタックは次のようにプッシュ:
あなたは、ブラウザの戻るボタンからページcにページから撤退すると、我々はスタックXからCとBポップに向けると、スタックY.に変身します 今回、このようなデータの2つのスタック:
今度は、別のページBを見たい、とあなたはBとし、我々がスタックに置かY、X内のスタックからポップ置く、ページBに戻るには[進む]ボタンをクリックしてください。このようなデータのこの時点で2つのスタック:
今回、新しいページのD bにページを介してジャンプする必要があり、cは、前方と後方のボタン通じないページが繰り返し参照することができますので、スタックY.を空にする必要性 このようなデータのこの時点で2つのスタック:
コードが実装されている場合、何がそれだろうか?あなたは考えることができます。
実際には、最初のメソッド内のコードは、あなたがルートの履歴レコード以上のアレイを追加することができ、これは、付加および欠失のアレイである上記チャートの一例として、二つの動作履歴に示すことができますここでは開始されません。
ここで、第二の方法論争教師王を参照して、データ構造及びアルゴリズムのメイ。
4.最後に
最初のブログよりアドレス:GitHubに
参考記事:米国のデータ構造とアルゴリズム