JS 返回上一頁並刷新,但不用重新加載整個頁面(ajax實現)


需求

有三個頁面A、B、C,點擊A=>B,點擊B=>C,在C中添加內容,點擊確定返回到B,此時B頁面需重新加載新的內容。再次點擊B的返回按鈕,希望返回到A而不是C。

===== 2017/5/10 更新 ======

IOS 瀏覽器的詭異表現:history.go(-1)返回上一頁后,頁面內容並不會刷新。在C頁面添加的內容,返回到B時並沒有更新新的內容,必須手動刷新。

經過debug,發現在ios瀏覽器中,返回上一頁后,頁面的 JS 代碼並未執行。我們猜測可能是緩存引起的,於是使用 meta 禁止了緩存,但仍然沒有效果。於是進一步猜測可能是瀏覽器內部機制導致——ios為了提升瀏覽網頁的效率,可能給已瀏覽過的網頁添加一個類似快照的東西,當點擊返回按鈕后,直接調用快照展示給用戶,省去了執行JS這一步驟(純靜態文件依然被緩存)。

於是想到一個hack方法:

//C頁面
sessionStorage.setItem('isHistory', 'true');

// B頁面
if(navigator.userAgent.match( /(?:iPad|iPod|iPhone).*OS\s([\d_]+)/ )) {
        var timer = setInterval(function(){
            if(sessionStorage.getItem('isHistory') == 'true') {
                sessionStorage.setItem('isHistory', 'false');
                timer = null;
                location.reload();
            }
        },30);
    }

===== end =====

分析需求

顯然,此需求有兩個功能:

  • 頁面中的返回上一頁功能
  • C中添加內容,返回B后刷新頁面,同時保證B頁面返回功能的正常使用

解決方案

針對第一個問題,我們很容易想到history.back()或者history.go(-1)

難點在第二個問題,最開始我是這樣解決的:loacation.href = document.referrer,此時,B頁面內容正確顯示,但點擊返回按鈕卻到了C

分析原因,原來是loacation.href相當於重新加載了一次B頁面,那么當前B頁面的上一頁自然就是C了。

有沒有辦法使得B頁面不重新加載,但更新內容呢?

使用Ajax!!!瀏覽器加載頁面后,會緩存HTML,每次加載頁面都會執行一遍JS

1、C 頁面點擊確定后使用history.go(-1),返回到B頁面

2、在 B 頁面通過$.ajax()獲取內容

var xhr = $.ajax({
  type: 'GET',
  url: '/api/xxx/xx',
  timeout: 5000,
  dataType: 'json',
  beforeSend: function(XHR){
    // todo
  },
  success: function(json){
    //
  },
  error: function(){},
  complete: function(xhr,status){}
})

3、重點,使用自執行函數渲染頁面

<script>
	function B(){};
	B.prototype.getData(){
      var xhr = $.ajax({...})
	};
	B.prototype.renderPage(){
      this.getDate();
      // render...
	};
	!function(window){
      var b = new B();
      b.renderPage();
	}(window)
</script>

這下應該成了吧。NO! C點擊確定后返回到B,B內容依然沒有更新。。。

這是為什么呢?

百度搜索無果,情急之下只有求救大神

大神說,可能是GET請求發出后,由於URL沒有變化,瀏覽器可能會從緩存中讀取數據而導致內容更新失敗。

  • 使用POST請求,強制從服務器獲取數據
  • 仍然使用GET,改變當前頁面的url,方法是在url末尾添加一段隨機字符串

兩種方法都能實現需求,這里再說說方法二:

var xhr = $.ajax({
  type: 'GET',
  url: '/api/xxx/xx',
  timeout: 5000,
  dataType: 'json',
  data: {flag: new Date().getTime().toString(36)}, // 在GET方法內添加一個任意key,隨機字符串改變
  beforeSend: function(XHR){
    // todo
  },
  success: function(json){
    //
  },
  error: function(){},
  complete: function(xhr,status){}
})


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM