移动端实现导航子模块点击自动居中的方法

1,704 阅读2分钟

最近开发移动端,遇到了一个滑动导航子模块点击自动居中的需求。通过几小时的努力,多种尝试后,实现了以下效果:

前两个模块点击时不会居中,之后每个模块,在点击后,自动去居中。 开始想法是使用css transform 去移动当前的盒子进行偏移,但出现一个问题,在移动到居中位置后,去滑动滚动条,因为偏移的原因,导致显示不全。 尝试去设置当前盒子滚动位置后,完美解决当前问题。 由于使用Vue框架,绑定事件后,不进行传参,通过target方法拿到当前点击的dom节点。 以下是代码:

  html:
    <div class="horizontal">
  <div :class="checkId == index ? ' child active':'child'"
       v-for="(item,index) in navList"
       v-bind:key="item.id"
       :data-id="item.id"
       :data-index="index"
       @click="horizontalChange">
    {{item.name}}
  </div>
</div>
js方法:
   horizontalChange (val) {
  this.checkId = val.target.getAttribute('data-index')
  // 获取当前点击的子元素
  let child = val.target
  // 获取当前视口的宽度
  let windowWidth = window.innerWidth
  // 获取视口减去子元素本身宽度后一半的值
  let diffWidth = (windowWidth - child.getBoundingClientRect().width) / 2
  // 获取当前需要移动的距离,计算方式是用当前元素距离父元素左侧的距离减去视口居中数值
  let targetOffset = child.offsetLeft - diffWidth;
  // 如果得到的值是负数,则表示当前子元素不需要滚动
  if (targetOffset < 0) {
    document.querySelector('.horizontal').scrollLeft = 0;
    return
  }
  // 设置当前需要滚动的盒子的滚动条位置
  document.querySelector('.horizontal').scrollLeft = targetOffset
  // parent.style.transform = 'translateX(-' + targetOffset / 100 + 'rem)';

},
  css样式:
  .horizontal {
overflow-x: auto;
margin: 0.3rem;
transition: scroll linear 0.5s;
scroll-behavior: smooth;
display: flex;

.child {
  flex-shrink: 0;
  padding: 0.1rem 0.2rem;
  color: #333;
  margin-right: 0.4rem;
  background: #f6f6f6;
  font-size: 0.28rem;
  border-radius: 0.3rem;
}
.child:last-child {
  margin-right: 0;
}
.child.active {
  color: #fff;
  background: #eb6100;
}

}

由于使用原生js方法,所以同样适用于pc端,灵活使用即可。