菜单栏底部线条切换效果

要实现的效果是当点击某一个菜单的时候,菜单的底部有一个线条高亮,从上一次的位置切换到点击的位置,而且需要添加动画效果。

首先我们的DOM结构是这样的,li 是显示每一个菜单的内容,我们添加了自定义的属性,用来区分在点击的时候具体是点击第几个的位置。线条是通过定位在最底下的。
class="wrapper"> class
="list" id="list"> class ="item" data-index="0">首页 class ="item" data-index="1">详情 class ="item" data-index="2">评价 class="line" id="line"> class="inner"> 在css上面,线条通过两个 div 控制,外层的宽度要和菜单的宽度保持一致,里面的宽度是具体线条显示的宽度。这样就能居中显示。
.wrapper {position: relative;}.list {display: flex;}.item {flex: 1;text-align: center;line-height: 36px;}.line {position: absolute;text-align: center;left: 0;bottom: 0;width: 0;transform: translate3d(0, 0, 0);transition: transform 0.3s ease-out;display: none;}.inner {width: 20px;height: 2px;background: red;display: inline-block;vertical-align: bottom;}
在JS里面,我们先需要获取每个菜单的宽度和距离页面左边的距离,然后绑定点击事件,根据自定义属性我们知道点击的位置,然后重新设置线条的偏移位置。
const list = document.getElementsByClassName('item')const line = document.getElementById('line')const listWrapper = document.getElementById('list')const resut = []for (let i = 0; i < list.length; i++) {const element = list[i]resut.push({width: element.offsetWidth,left: element.offsetLeft})}line.style.width = `${resut[0].width}px`line.style.display = 'block'listWrapper.onclick = function (e) {const index = e.target.dataset.indexconst width = resut[index].widthline.style.width = `${width}px`const left = resut[index].leftline.style.transform = `translate3d(${left}px, 0, 0)`}
设置了宽度是为了防止有些菜单宽度不一样,所以为了能居中,我们就需要点击的时候去重新设置一下。还有就是尽量使用 transform 属性而不是 left 设置偏移,动画性能效果更好。
评论
