使用history儲存列表頁ajax請求的狀態

lujs發表於2018-01-19

問題

最近碰到兩個問題:

  1. 從首頁進入列表頁之後,點選下一頁的時候,使用ajax請求更新資料, 然後點選瀏覽器“後退”按鈕就直接返回到首頁,實際這裡想要的效果是返回列表頁上一頁。
  2. 在列表頁分頁為2的頁面進入詳情頁,然後點選“後退”按鈕,返回的事列表頁分頁為1的頁面。沒法記住之前分頁狀態。

優化前程式碼

使用history儲存列表頁ajax請求的狀態
程式碼如下,在頁數變化的時候,去非同步請求資料,渲染頁面。

const currentChange = (currentPage) => {
    ajax(`請求地址/${currentPage}`)
    .then(renderPage)
}
複製程式碼

history

經過幾番搜尋,發現可以用History 介面來實現我們想要功能。

history.pushState()

按指定的名稱和URL(如果提供該引數)將資料push進會話歷史棧,資料被DOM進行不透明處理;你可以指定任何可以被序列化的javascript物件。具體描述可以參考文件

通過history.pushState(state, title, url)可以修改會話歷史棧,把我們需要儲存的資料存到state中,這裡我們存入一個物件,屬性為當前頁數;title一般沒什麼用,這裡傳入null;url會修改當前歷史紀錄的地址,瀏覽器在呼叫pushState()方法後不會去載入這個URL

假設當前currentPage為1,當前url為www.example.com/search/index

...
const pushState = () => {
    const url = `/search/index/${currentPage}`
    history.push({
        page: currentPage
    }, null, url)
}

const currentChange = (currentPage) => {
    ajax(`請求地址/${currentPage}`)
    .then(res =>{
        pushState(currentPage)
        renderPage()
    })
}
...
複製程式碼

現在程式碼執行順序是:頁數改變 => ajax請求 => pushState => renderPage()
在pushState之後當前url變成www.example.com/search/index/1

window.onpopstate

現在我們通過history.pushState()方法把狀態存入歷史會話中了,接下來就要監聽window.onpopstate事件

參考mdn文件window.onpopstate

每當處於啟用狀態的歷史記錄條目發生變化時,popstate事件就會在對應window物件上觸發.

呼叫history.pushState()或者history.replaceState()不會觸發popstate事件. popstate事件只會在瀏覽器某些行為下觸發, 比如點選後退、前進按鈕(或者在JavaScript中呼叫history.back()、history.forward()、history.go()方法).

接下來監聽這個事件

window.addEventListener("popstate", (event) => {
	if(event.state !== null){
	    page = event.state.page
	    changeCurrentPage(page) // 修改當前頁數
	}
})
複製程式碼

當popstate觸發時,會修改當前頁數,然後觸發之前定義的currentChange方法,更新資料,渲染頁面。

問題2

到此為止,問題1就解決了。 接下來要解決問題二:從詳情頁返回列表頁,記住之前的狀態
這裡我用url來記錄狀態,之前pushState推入的url就派上用場了。 只要把進入頁面首次請求的地址改成當前url就可以了
假設之前push的url為www.example.com/search/index/5,從詳情頁返回之後url還會顯示www.example.com/search/index/5

mounted () {
    ajax(location.href)
}
複製程式碼

這樣就完成了。 當然如果你的狀態比較複雜,可以把資料存入本地Storage,新增一些判斷即可

寫文章可以得非同步社群的書!愛讀書的技術人都在非同步社群。我想要讀《Python核心程式設計(第3版)》,希望你也能夠喜歡

相關文章