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

問題

最近碰到兩個問題:javascript

  1. 從首頁進入列表頁以後,點擊下一頁的時候,使用ajax請求更新數據,

而後點擊瀏覽器「後退」按鈕就直接返回到首頁,實際這裏想要的效果是返回列表頁上一頁。java

  1. 在列表頁分頁爲2的頁面進入詳情頁,而後點擊「後退」按鈕,返回的事列表頁分頁爲1的頁面。無法記住以前分頁狀態。

優化前代碼


代碼以下,在頁數變化的時候,去異步請求數據,渲染頁面。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/1url

window.onpopstate

如今咱們經過history.pushState()方法把狀態存入歷史會話中了,接下來就要監聽window.onpopstate事件spa

參考mdn文檔 window.onpopstate

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

調用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,添加一些判斷便可

相關文章
相關標籤/搜索