如何用堆栈来保存和恢复滚动条位置
問題背景
在單頁應用中,翻頁一般通過display:none將先前的面板(一般就是個div容器)隱藏,然后將本次需要展現的面板設置成display:block(當然,還可能加點css切換動畫,不過不影響我們本次的討論結果,故不予關注),一般情況下,這樣的處理方式是沒啥問題的,不過如果之前的面板本身有滾動條,那么跳轉到新面板之后再返回到原先面板就會導致滾動條位置直接變成0,這主要是當元素的display為none時,元素不占據位置,等到display非none的時候才會被重新布局,渲染。
我們以jq.ui(一個用于構建jqMobi應用的用戶界面庫)為例說明下怎么解決單頁應用中切換頁面導致的滾動條位置信息丟失問題
思路
在老頁面被display:none之前用一個堆棧存儲下當前頁面的滾動條位置,然后在用戶點擊瀏覽器返回按鈕的時候取出棧頂記錄的滾動條位置信息并調用window.scroll滾動到指定位置即可。
基于jq.ui的實例
1、在jq.ui源碼中頁面切換之前手動觸發個事件(用于在自己的代碼中捕捉此事件并記錄老頁面滾動條位置信息)
/*在老的panel被display:none之前觸發beforeHideOldPanel事件, *用于記錄當前滾動條位置,以便于返回上一頁時滾動到指定位置*/ jq(oldDiv).trigger('beforeHideOldPanel');2、在頁面上監聽第一步中觸發的beforeHideOldPanel事件和popstate(瀏覽器回退事件)以及loadpanel(加載面板事件),當beforeHideOldPanel事件被觸發且當前不在回退時記錄滾動條位置,當loadpanel事件被觸發且當前正在回退時從堆棧中取出滾動條位置并調用window.scroll手動滾動到指定位置
// 由于jq.wow.js中通過display:none方式切換面板,導致老的panel滾動條信息丟失 // (display:none元素無高度),點擊返回上一頁時會自動定位到頂部 // 此處通過一個簡單的堆棧記錄老頁面的滾動條信息,退回上一頁時手動調用window.scroll滾動到指定位置 function resetScrollWhenPopstate() {//借助數組實現個簡單的堆棧var scrollStack = {list: [],push: function (obj) {this.list.push(obj);},pop: function () {return this.list.pop();}};$('.panel').on('beforeHideOldPanel', function (e) {// 僅非回退時才記錄滾動條位置if (!isPopStating) {scrollStack.push({oldPageId: e.currentTarget.id,oldScrollTop: document.documentElement.scrollTop || document.body.scrollTop});}}).on('loadpanel', function (e) {// 僅回退頁時才恢復滾動條位置if (isPopStating) {var obj = scrollStack.pop();if (obj && obj.oldPageId == e.currentTarget.id) {window.scroll(0, obj.oldScrollTop);}}});// 標示是否正在回退var isPopStating = false;window.addEventListener('popstate', function () {isPopStating = true;setTimeout(function () {isPopStating = false;}, 200);}); }總結
看似簡單的堆棧其實還是有挺大用處的,算法和數據結構這東西看來還是需要學習學習(@ο@) 哇~
總結
以上是生活随笔為你收集整理的如何用堆栈来保存和恢复滚动条位置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 移动spa商城优化记(一)---首屏优化
- 下一篇: 如何优雅的链式取值之 MayBe 函子