需求場景:
- 非推薦商品詳情頁返回的時候彈出彈窗推薦商品,點擊彈窗按鈕可以直接訪問推薦商品;
- 只有直接進入商品詳情頁返回才會彈出推薦商品彈窗;
- 每個用戶訪問只能彈一次(除非清除緩存)。
需求分析:
1. 判斷是否直接進入商品詳情頁可以在商品詳情頁直接判斷 history.length ,如果是則 history.length=2 ;
2. 每個用戶只能彈一次可以保存一個標志值 hasBeenRecommended=true 到緩存中,有了這個標志值就不再彈出;
3. 返回的監控,還是要監聽頁面的popstate,如果要阻止原來的返回操作的話,就要給頁面棧添加一個空棧:
history.pushState(null, null, document.URL);
實例代碼:
1. vue框架內頁面初始化時判斷是否需要推薦彈窗:
...... //修改歷史記錄狀態,需要放在商品數據初始化之后 if(history.length<=2 && !localStorage.getItem("hasBeenRecommended")) { //獲取推薦數據信息,頁面返回標識修改及頁面棧加入空棧操作在判斷非當前頁面之后再進行 this.getRecommendGoodInfo(); } ......
注:
本例需要調用后端接口動態配置,可以在獲取商品詳情數據之后進行,也可以在頁面初始化時查詢商品詳情時異步進行,這個影響不大,盡量不要在返回監聽的邏輯中處理,如果推薦商品數據需要調用后端接口的話,還是放在頁面初始化時處理比較好。
2. 獲取推薦商品詳情信息:
/** * 獲取推薦權益卡信息數據 */ getRecommendGoodInfo: function() { var self = this self.$ajax({ method: 'post', url: self.$utils.DOMIN + 'goods/getAdvert', }).then((response) => { var data = response.data.d if(data && data.goodsId != self.$route.query.goodsId) { //給頁面添加空的頁面棧,同時給推薦彈窗填充數據 history.pushState(null, null, document.URL); //保存阻斷返回的標志到緩存中 localStorage.setItem('stopBack',true); //填充彈窗元素數據源 self.recommendGoodInfo = data } }).catch(function(error) { console.log(error); }); }
注:給頁面添加空的頁面棧的同時保存一個標志值到緩存中,那么在返回的時候如果有這個值就彈出彈窗,同時將這個值進行重置或清除。
3. 返回監控,在vue框架外圍處理:
/** * 返回監控,若緩存中返回標識為666,則彈出推薦權益卡彈窗,同時緩存中保存已經彈出推薦彈窗的標識 */ window.addEventListener("popstate", () => { if(localStorage.getItem("stopBack")) { //使用jquery或原生js的方式是彈窗顯示 $(".showRecommendModal").fadeIn() localStorage.removeItem('stopBack') localStorage.setItem("hasBeenRecommended", true) } })
注:監聽瀏覽器的返回本身就會破壞掉vue的路由,所以這個操作只能在vue框架外圍來進行。如此,彈窗的數據是在vue框架中填充的,彈窗的顯示是在原生js的返回監控中處理的。
后記:
整體來說,感覺上邊的這種方案還是比較好的,當然如果喜歡原生js的話,也可以在vue框架中將推薦商品數據保存到緩存中,然后在返回監控的邏輯中以操作DOM的方式將彈窗追加到html結構中去,不過個人是不喜歡操作DOM的。