随笔:详情的快速定位

实现效果

在项目中经常碰到详情效果有多个内容区块,需要根据快速导航做定位,如下记录实现的过程用作日后的参考。

实现分析:左侧作为可滚动区域class为side-nav-body,右侧的快速定位区域class为side-nav-list。其中side-nav-body占据屏幕高度,并且多余内容内部可以滚动,而side-nav-list需要常驻在顶部位置,所以在dom层级上两者应该是同一层位置,dom结构如下:

  • 概览
  • 基本信息

滚动:当点击li节点的时候需要触发div.side-nav-body的滚动,触发之前我们需要计算滚动高度。这里需要使用到两个值,一个是offset的值,一个是scollTop的值,这里分别解释他们的具体含义。

offset()的返回结果为dom结构距离浏览器的视口的顶部和最左边的距离,可以通过$('dom').offset()得到形如 {top: 120, left: 580}的结构。对于.side-nav-body区域内没有padding和滚动的情况,.side-nav-body.sect-overview offset()的结果是一样的,对于.side-nav-body内部有滚动的情况下,我们需要计算的就是这两个offset().topoffset

scollTop()的返回结果为内容区域的相对顶部滚动了多少,如果内容往上滚动了100px,那返回值就是100。

这里给出计算公式:

容器滚动高度 = 容器原滚动高度 + 需要偏移的高度 = 容器滚动高度 + 子容器距离视口顶部的距离-父容器距离视口顶部的距离

转化为示意表达式为:

let originScroll = container.scrollTop();
let offset = sect.offset().top - container.offset().top;
container.scrollTop(originScroll + offset)

在本例中为了增加动画效果,不直接使用scrollTop而是使用animate,最终的实现代码为:

function navTo(key) {
  let container = $('.side-nav-body');
  let sect = $(`.${key}`, container);
  let offset = sect.offset().top - container.offset().top;
  let originScroll = container.scrollTop();
  body.animate({
    scrollTop: originScroll + offset
  }, 300)
}

你可能感兴趣的:(随笔:详情的快速定位)