一般我们翻阅百科的时候,如果文章过长的话,就不太方便找到我们想要的资源。此时有一个定位导航的话,那可真是帮大忙了~今天,就来聊聊这种常见的锚点定位导航的原理以及是如何实现的。
定位原理
首先我们来了解一下,什么锚点?
在海上,水手们会将锚丢入海中,或者靠岸时将锚抛上岸,其固定目的是让船固定位置。而**锚点(anchor)**也是一样,只不过场景不同罢了。
页面锚点定位可以通过name
或者id
属性来定位。name
已经被HTML5
废弃了,就不再多提。
在页面上,每个id
都会自动创建一个锚点,同时还会生成一个hash
,表示所处的文档位置。浏览器可以通过hash
来确定位置,使用的方式一般如下:
1 2 3 4
| <a href="#title">跳到title</a>
|
这个hash
值我们可以通过浏览器的APIlocation.hash
取到。但值得注意的是,跳转hash
的话是不会像服务端发送请求的(除了第一次请求页面)。
深入分析
但我们光知道跳转的原理可不够,只要你尝试了上面的跳转方法后,你会发现浏览器跳转方式是很唐突的。它会直愣愣的跳到指定位置(或者没有找到指定位置会,跳到页面最上面),这在用户看来是十分生硬的,在体验上这个交互并不太友好。这时产品就会要求我们对此处进行优化~ 不过知道了上面的原理后,我们也可以直接使用js的方式来代替这种原生的默认跳转:
首先我们页面的结构大致如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <nav class="nav"> <a class="actived" href="#title1">第一组图片</a> <a href="#title2">第二组图片</a> <a href="#title3">第三组图片</a> </nav>
<main id="content"> <article id="title1" class="item"> </article>
<article id="title2" class="item"> </article>
<article id="title3" class="item"> </article> </main>
|
页面布局固定了后,元素离页面顶部的距离可以通过offsetTop
来获取到。同时我们可以操作滚动容器(html)的scrollTop
来修改滚动位置。嘿,这样一上(目标距离顶部的高度)一下(滚动条),两个API
双剑合璧后,我们就可以点击模拟滚动啦..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| var $menu = $('.nav'); var $menuList = $menu.find('a');
$menuList.each(function() { var $this = $(this); $this.click(function(e) { var id = $this.attr('href').replace(/#/g, '');
var top = $('#' + id).offset().top - 60;
$('html').animate({ scrollTop: top }, 1000); }); });
|
蹡蹡!在页面中调试会发现,点击后页面会平滑的滚动到指定的锚点~ 除此之外,我们还得再添加一个功能:在页面滚动的时候,能让用户知道自己所在的位置~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| var contentList = $('#content').find('.item');
$(window).scroll(function(e) { var top = $(document).scrollTop();
var currentID = ''; contentList.each(function() { var $this = $(this);
var itemTop = $this.offset().top;
if (top > itemTop - 250) { currentID = '#' + $this.attr('id'); } else { return false; } });
var currentLink = $menu.find('.actived'); if (currentID && currentLink.attr('href') !== currentID) { currentLink.removeClass('actived');
$menu.find("[href='" + currentID + "']").addClass('actived'); } });
|
这样就锚点定位导航的功能就大功告成啦~ 最后将测试代码放入了codepen上了,感兴趣的同学可以去看看。