導航欄續之自動切換樓層

滾屏時自動高亮當前樓層對應的tab

這個其實很簡單,就是偵聽scroll事件,而後依據滾動高度和各樓層的offset top值,計算出與當前樓層最接近的那個樓層,最後高亮相應tab便可。緩存

var top = $win.scrollTop();
var i = 0;
// 尋找當前樓層的序號
floorTops.forEach(function(ot, j) {
  if (ot <= top + navHeight) i = j;
});
cache[options.key] = i;
// 高亮對應的tab
var tab = $nav.find('li').eq(i);
if (!tab.hasClass('active')) {
  highlight(tab);
}

floorTops是什麼呢?它緩存了各個樓層offset top值,從而避免了沒必要要的頻繁的頁面重繪。session

var floorTops = (function (nav){
  var tops = [];
  var floors = $(options.floor);
  nav.find('li').each(function(i) {
    tops[i] = Math.floor(floors.eq(i).offset().top);
  });
  return tops;
})($nav);

頁面刷新後自動定位到原樓層

這個也不難實現,緩存當前樓層便可,好比sessionStorage。 刷新時,讀取這個值,若是有且大於0,定位到對應樓層。this

var curFloor = +cache[options.key];
if (curFloor) {
  $nav.find('li').eq(curFloor).click();
} else { // 第一樓層或初次進入,完整顯示首屏內容
  window.scrollTo(0, 0);
}

這裏定位到特定樓層,是經過觸發對應tab的響應事件實現的:code

$nav.on('click', 'li', function() {
  var li = $(this);
  var i = li.index();
  if (!li.hasClass('active')) {
    highlight(li);
  }
  cache[options.key] = i;
  var offset = floorTops[i];
  $win.scrollTop(offset - navHeight);
});

那麼,爲何緩存樓層而非具體的scrollTop值呢?由於數據是動態的,每次樓層高度可能不同,而樓層是固定的,這樣至少能夠避免誤定位。事件

最後提醒一下,safari在隱私模式下,本地存儲寫操做會拋異常,須要檢測可用性:rem

var cache = win.sessionStorage;

try {
  cache.setItem('test', '1');
  cache.removeItem('test');
} catch (e) {
  cache = {};
}

有空了,作個演示demo分享:)io

相關文章
相關標籤/搜索