這個其實很簡單,就是偵聽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