UDN-企业互联网技术人气社区

板块导航

浏览  : 560
回复  : 2

[原生js] 仿写百度百科的目录树

[复制链接]
小辫儿的头像 楼主
发表于 2017-1-7 15:22:26 | 显示全部楼层 |阅读模式
  一、首先来看一下需求(截图为百度百科“医保”词条):

  1、点击右侧的目录树,左侧跳转到指定的锚点位置;

  2、滚动鼠标,游标跟随一起滚动至响应链接位置
2.png

  二、实现思路

  1、针对第一个需求,只需要设置游标所在div和右侧列表div的position为fixed,根据浏览器窗口定位,然后给左侧文章各区块增加id,为右侧列表每一项增加对应的href属性指向响应的锚点即可;

  2、针对第二个需求,定义鼠标的滚动事件mousewheel(在ff下事件为DOMMouseScroll),当时自己琢磨了半天用各种方法计算,但效果始终无法达到要求,后来分析了百度的实现源码恍然大悟,具体实现参考下图和代码部分。
1.png

  三、代码实现
  1. /**定于延时执行函数**/
  2.     var timeFun = null;
  3.     /**找到当前页面滚动到的锚点位置**/
  4.     var findHref = function(){
  5.         var $links = $('.link');
  6.         var windowScrollTop = $(window).scrollTop();
  7.         var maxDistance = 10000;
  8.         var result = $links.eq(0);
  9.         $.each($links,function(i,link){
  10.             var curDistanceToTop = Math.abs($links.eq(i).offset().top - windowScrollTop);
  11.             /**if(maxDistance > curDistanceToTop && ($links.eq(i).offset().top < (windowScrollTop + $(window).height()))){
  12.                 maxDistance = curDistanceToTop;
  13.                 result = $links.eq(i);
  14.             } 这段代码相当于下面这一句代码,优秀的代码就应该拿来多学习!**/
  15.             maxDistance > curDistanceToTop && $links.eq(i).offset().top < windowScrollTop + $(window).height() && (maxDistance = curDistanceToTop,result = $links.eq(i))
  16.         });
  17.         return result;
  18.     };
  19.     /***使用jQuery创建移动动画*/
  20.     var move = function (dis) {
  21.         var $arrow = $('.arrow');
  22.         $arrow.animate({top:dis},'normal');
  23.     }
  24.     /**滚轮事件Handler**/
  25.     var wheelHandler = function(e){
  26.         clearTimeout(timeFun);
  27.         timeFun = setTimeout(function(){
  28.             var href = findHref();
  29.             var index = href[0].id.substring(1);
  30.             var dis = 30*(index-1)+10;
  31.             move(dis);
  32.         },600);
  33.     };
  34.     /***注册滚轮事件*/
  35.     $('body').on('mousewheel',wheelHandler);
复制代码

  四、Tips

  1、$('.link')[0]返回的是普通的Dom对象,而代码中使用$('.link').eq(0)返回的是jQuery对象,jQuery对象才有.offset()方法。

  补充说明:eq返回的是jquery对象,而get(n)和索引返回的是dom元素对象。

  2、为什么要使用延时执行函数,并且在wheelHandler中clearTimeout(timeFun)?

  因为我们正常滚动鼠标会触发多次的mousewheel事件,为了防止jQuery动画出现卡顿的现象,将代码设计成只在鼠标滚轮停下来的时候去触发,clearTimeout做的事情就是只要鼠标滚轮还在滚动,进入wheelHandler方法,就把前面已加入到延时执行队列中的方法清除,这样就可以做到只对最后一个滚动触发动画事件,看上去就好像鼠标滚轮停止滚动了才去触发一样。

相关帖子

发表于 2017-1-7 15:22:56 | 显示全部楼层
纯粹路过,没任何兴趣,仅仅是看在老会员的份上回复一下
使用道具 举报

回复

发表于 2017-1-7 15:22:57 | 显示全部楼层
js太强大了,好多工作前端都可以做了…
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部