1. 程式人生 > >一篇文章圖文並茂地帶你輕鬆實踐 HTML5 history api

一篇文章圖文並茂地帶你輕鬆實踐 HTML5 history api

## HTML5 history api ### 前言 由於筆者在網路上沒有找到比較好的關於 `history api` 的實踐案例,有的案例過於雜亂,沒有重點,有些案例只是告訴讀者 `api` 是什麼,卻沒告訴怎麼用,本文章從零開始帶讀者實踐 `history api` ,建議和筆者一起寫一遍。 ### 效果 注意 `url` 變化,另外用到了 虎褲里老師 和 狼大老師 的圖,侵權馬上刪。 ![](https://img2020.cnblogs.com/blog/2286610/202102/2286610-20210212145252698-1819971383.gif) ### 流程 1. `html` 部分 需要引入 `jquery` ```html history html5 ``` 2. `css` 部分 ```css .row { display: flex; justify-content: space-around; } .image { width: 25%; height: 25%; padding: 20px; cursor: pointer; } ``` 3. 等待頁面 `dom` 載入完畢再執行 `JS` ```js window.onload = () =>
{ // ... } ``` 4. 獲取 `btn` 新增事件 獲取請求所需的 `id` 以及介面需要展示的 `url` 路徑 ```js const btns = document.querySelectorAll(".btn"); btns.forEach(btn => { const dataId = btn.getAttribute("data-id"); // 請求 id const dataName = btn.getAttribute("data-name"); // 頁面 url 路徑 btn.addEventListener("click", () =>
{ // ... }); }); ``` 5. 模擬網路請求 接上方的程式碼,這裡的話我寫了一份模擬資料 ```js { "images": [ "./images/牛牛.jpg", "./images/虎虎.jpg" ] } ``` ​ 並在對應資料夾下存放了圖片,接下來進行 `ajax` 網路請求 ```js btn.addEventListener("click", () => { $.ajax({ url: "./mock/mock.json", success: (res) => { const { images } = res; const state = images[dataId]; displayContent(state); // 接下來會提到這個函式 history.pushState(state, null, dataName); // 接下來會提到這個函式 }, }); }); ``` ​ 這裡的話,一般來說是傳入 `id` 給服務端返回一個圖片的 `url` 由於為了實現簡單,全部返回後,根據先前從 `dom` 屬性上獲得的 `dataId` 獲取圖片的 `url` 6. 根據獲得的 `url` 進行展示 ```js const image = document.querySelector(".image"); const displayContent = (src) =>
{ image.setAttribute("src", src); }; ``` 7. 頁面變化後,利用 `html5 history api` 進行修改頁面地址,並傳入 `state` ```js history.pushState(state, null, dataName); ``` 其中第一個引數後面有個監聽事件會用到,而第二個引數代表標題,沒必要傳,第三個引數是路徑。 如果當前路徑是 `/history` 則如果傳入的路徑是 `cow` 則會變成 `/history/cow` 經過上面的幾個步驟,已經成功完成了利用按鈕切換介面的時候,展示不同的圖片資訊。 這個時候,如果點選返回或者頁面的前進按鈕,跳轉到上一頁或下一頁,是無法顯示網頁資訊的。 8. 前進後退顯示網頁資訊 ```js window.addEventListener("popstate", (e) => { const { state } = e; if (state) displayContent(state); }); ``` 這裡的 `state` 就是前面 `pushState` 傳的 `state`,可以根據這個 `state` 渲染當前介面,這就保證了在前進後退的時候渲染對應的影象。 這個時候當我們點選前進和後退的時候,基本是已經可以展示對應的介面的,這樣非常好,但是仍然有個問題,當後退到第一個介面的時候,沒有資料 9. 替換第一個介面的資料 ```js history.replaceState("./images/虎虎.jpg", null, location.href); image.setAttribute("src", "./images/虎虎.jpg"); ``` 這裡的話,把第一個介面的資料補充上,其實一般都是經過網路請求的,這裡省略了。現在還存在一個問題,如果跳到某個介面後,重新整理,可能會出現獲取不到資源的情況。 這很正常,例如我們在 `/history` 下有一個 `index.html` 檔案,那麼訪問 `/history` 是可以直接訪問到這個檔案的,但是當我們通過上述方法跳轉路由的時候 `/history/cow` 並不存在 `index.html` 檔案,這意味重新整理介面後獲取不到對應的資源了,這個時候上線後還需要 `nginx` 的輔助配置 10. 通過 `nginx` 的 `url` `rewrite` 配置,使得總是命中 `history/` ### 總結 不知道大家有沒有用過之前的 `vue router` 裡面如果開啟了 `mode: history` 的話,最後還要通過 `nginx` 進行輔助配置,可能就是這個