淺談history對象以及路由插件原理

来源:https://www.cnblogs.com/karthuslorin/archive/2018/08/09/9450068.html
-Advertisement-
Play Games

簡介 History對象最初設計用來表示視窗的瀏覽歷史,但是,出於隱私方面的原因,History對象不再允許腳本訪問已經訪問過的實際URL。雖然,我們不清楚歷史URL,但是,我們可以通過History對象的內置屬性方法進行跳轉。 對象屬性 length 該屬性代表著瀏覽器歷史列表中的URL數量。初始 ...


簡介

History對象最初設計用來表示視窗的瀏覽歷史,但是,出於隱私方面的原因,History對象不再允許腳本訪問已經訪問過的實際URL。雖然,我們不清楚歷史URL,但是,我們可以通過History對象的內置屬性方法進行跳轉。

對象屬性

length

該屬性代表著瀏覽器歷史列表中的URL數量。初始值為1,如果當前視窗先後訪問了兩個網址,那該屬性的值變為2。

history.length          // 1
// 訪問了一個新的URL
history.length          // 2

state

HTML5新增屬性,返回一個表示歷史堆棧頂部的狀態的值,這是一種可以不必等待popstate 事件而查看狀態的方式。

scrollRestoration

允許Web應用程式在歷史導航上顯式地設置預設滾動恢復行為。此屬性可以是自動的(auto)或者手動的(manual)。

對象方法

go方法

go方法是History對象三個方法中的核心方法,通過go方法可以完美替代其他的兩個方法。該方法接收一個可選參數,這個參數可以是number也可以是URL

ps:經過多次試驗,傳入URL參數貌似沒有作用,有待後續研究

當使用number參數時,頁面會跳轉到History的URL列表的相對位置。比如當傳入參數為-1,則相當於點擊瀏覽器後退按鈕的效果;當傳入參數為1時,相當於點擊瀏覽器前進按鈕;當不傳參數或者傳入參數為0時,頁面會刷新。

window.history.go(-1)           // 後退
window.history.go(1)            // 前進
window.history.go(0)            // 刷新
window.history.go()             // 刷新

tips:當傳入的number對應的位置沒有URL,則該條語句會靜默失敗

forward方法

forward方法可以載入歷史列表中的下一個URL,類似於go(1),實現了點擊瀏覽器前進按鈕的效果。

window.history.forward()        // 前進
window.history.go(1)            // 前進

back方法

back方法可以載入歷史列表中的上一個URL,類似於go(-1),實現了點擊瀏覽器後退按鈕的效果。

window.history.back()           // 後退
window.history.go(-1)           // 後退

tips:當URL隊列中沒有上一個URL時,back方法會失效;同理,當URL隊列中沒有下一個URL時,forward方法會失效。

HTML5新增方法

HTML5為History對象添加了兩個新方法,pushStatereplaceState方法,用來在瀏覽歷史中添加和修改記錄。

pushState方法

pushState方法接收三個參數:

  • state:一個與指定網址相關的狀態對象,popstate事件觸發時,該對象會傳入回調函數。如果不需要這個對象(即不需要傳參),可以設為null
  • title:新頁面的標題,但是大部分瀏覽器目前都忽略這個值,所以這裡也可以設為null
  • url:新的網址,必須與當前頁處在同一域,瀏覽器的地址欄將顯示這個網址

比如當前的網址是localhost:63342/1.html,使用pushState方法在瀏覽記錄中可以添加一條新的記錄:

window.history.pushState({params: 'aaa'}, null, '2.html')

輸入這行語句後,瀏覽器地址欄中的URL變為了localhost:63342/2.html,但是無論這是不是一個真實網址,它都不會跳轉,這隻是一條歷史記錄。此時,可以通過state取到狀態。

此時,如果你前往下個地址後點擊後退按鈕,頁面將返回到localhost:63342/2.html,此時,也可以通過state屬性取到狀態。

window.history.state            // {params: "aaa"}

tips:如果pushState的第三個參數是一個跨域網址,控制台會報錯,這主要是因為安全問題,防止不法分子偽裝URL

window.history.pushState(null, null, 'www.baidu.com')       // 報錯

replaceState方法

該方法基本和pushState一致,但是不同的是,該方法會直接替換當前的歷史記錄。

路由插件的原理

傳統的History用法是操縱瀏覽器進行前進或後退的跳轉,用處不是很大。但是,HTML5新增的方法為其帶來了脫胎換骨的變化。

眾所周知,vue-router等一眾路由插件實現的功能是更新頁面的視圖,但是卻不重新請求頁面,也就是說,其實,他們並沒有實際進行了跳轉,而是修改了頁面的DOM並通過修改頁面的URL來模擬跳轉。

在HTML5之前,頁面路由只有hash模式,而HTML5中History對象的新增方法,帶來了另一種模式:history模式。

hash模式

在HTML5之前,vue-router是通過修改URL的hash值(URL中#開始的字元串,不瞭解的同學可以看我的上一篇文章)來達到修改頁面URL並生成歷史記錄,但卻不會重新請求頁面。所以,不使用vue-router中history模式的情況下,你會發現你的路徑前總會有一個#

比如,你在vue-router中設置的路徑是/b,在你的想象中,路徑應該是http://localhost:8080/b,但是,現實很骨感,實際路徑是:http://localhost:8080/#/b,原因就是因為沒開啟history模式的情況下,vue-router是通過hashchange事件來監聽URL中hash的改變並通過修改hash來模擬路徑的變化。

由於通過window.location.hash修改hash是會有歷史記錄產生的,所以,在SPA中,依然可以通過後退、前進按鈕來控制路由的跳轉。

hash模式最大的優點是相容性強,可以相容一眾老式瀏覽器。而它最大的缺點是,頁面URL中一直掛著一個難看的#,這一點連vue-router的官網也對其進行了吐槽。

有需求就有功能,所以,當HTML5發佈後,又有了history模式。

history模式

看到這裡,如果認真看了pushState方法的同學應該已經差不多明白了,vue-router的history模式就是通過HTML5中History對象的pushState方法進行模擬的。

當vue-router每次需要跳轉頁面時,頁面DOM的修改方式和時機並沒有改變,和hash模式一樣。但是,修改URL的方式改變了。此時,有了pushState方法,可以不用修改醜陋的hash模擬而是直接在歷史記錄中添加一條新的URL。

那麼,沒有了hash,如何監聽URL的改變呢?HTML5還提供了一個popstate事件,當用戶點擊前進、後退按鈕,或者調用backforwardgo方法時觸發,可以監聽URL的改變。

在這裡提一句,使用history模式,就連路由傳值都有更好的方式——使用pushState的第一個參數進行傳值,使用History的state屬性進行取值。

當使用了history模式時,使用vue-router跳入/b時,此時的頁面URL不是醜陋的http://localhost:8080/#/b,而是預料之中的http://localhost:8080/b

// hash模式
window.location.href            // http://localhost:8080/#/b

// history
window.location.href            // http://localhost:8080/b

總結

雖然,history模式提供了完美的URL顯示,但是,正所謂魚和熊掌不可兼得,相容性和美觀也不可兼得。只有相容了HTML5的瀏覽器(IE10+)才能使用history模式,不然,就老實的繼續使用hash模式吧。

所以,使用何種模式,還是取決於軟體的相容性,如果不需要相容低級瀏覽器,那就放心大膽的使用history模式吧!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 既接到電話狀態監聽的需求之後再次添加了截屏狀態的監聽,當使用 App 時若用戶執行截屏操作需要對當前狀態進行監聽操作,下麵有兩種方法,其中可以替換截屏的圖片內容(Plan A),也可以彈出提示框(Plan B),廢話不多說步驟如下. 此次分享到此結束,希望內容能對大家實際有所幫助,有什麼不足之處歡迎 ...
  • 前言 init進程,它是一個由內核啟動的用戶級進程,當Linux內核啟動之後,運行的第一個進程是init,這個進程是一個守護進程,確切的說,它是Linux系統中用戶控制項的第一個進程,所以它的進程號是1。它的生命周期貫穿整個linux 內核運行的始終, linux中所有其它的進程的共同始祖均為init ...
  • 1. ctrl + shift + n: 打開工程中的文件,目的是打開當前工程下任意目錄的文件。 2. ctrl + j: 輸出模板 3. ctrl + b: 跳到變數申明處 4. ctrl + alt + T: 圍繞包裹代碼(包括zencoding的Wrap with Abbreviation) ...
  • 一,效果圖。 二,代碼。 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>html標題</title> </head> <body> <!--標題--> <h1>這是標題h1</h1> <h2>這是標題h2</h2> <h3>這 ...
  • 本節列舉了一些簡單的HTML例子,幫助大家更感性地認識HTML標簽。是不是對一些標簽還不熟悉?別擔心,後面幾個章節會有詳細說明,先跑幾個例子看看效果吧。 HTML文檔相關標簽所有HTML文檔必須以<!DOCTYPE html>聲明開頭。 HTML文檔則以<html>開頭,以</html>結尾。 HT ...
  • 什麼是HTML?HTML是一種標準的標記語言,用這種語言可以創建web頁面。 HTML是一種超文本標記語言HTML使用一些標記來描述頁面的結構HTML中的元素(elements)是構建頁面的基礎HTML用標簽(tags)代表網頁元素各種不同的標簽(如頭部標簽,表格標簽,圖片標簽)彼此分工又相互組合, ...
  • 棧(stack)又名堆棧,它是一種運算受限的線性表。其限制是 僅允許在表的一端進行插入和刪除運算 。這一端被稱為棧頂,相對地,把另一端稱為棧底。 一、實現一個棧類Stack 基於堆棧的特性,可以用數組做線性表進行存儲。 初始化 類的結構如下: 接下來,就是在原型上,對 、`出棧 清空棧 讀取棧頂 讀 ...
  • CSS介紹 學前端必備掌握 樣式, 為層疊樣式表,用來定義頁面的顯示效果,加強用戶的體驗樂趣,那麼如何用 到`html`中呢? style屬性方式 利用標簽中的 屬性來改變顯示樣式 在 中加入 標簽 鏈接方式 總結CSS 選擇器名稱 { 屬性名:屬性值; ……. } 屬性與屬性之間用 分號 隔開 屬 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...