这个其实很简单,就是侦听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