效果图:
<a-timeline>
<a-timeline-item v-for="(item,index) in newdirectoryArr" :key="index" :class="currentClass(index)" @click="currentInfo(index)">
{{item.timeLineName}}
</a-timeline-item>
</a-timeline>
newdirectoryArr:
[
{
"timeLineName": "基本信息",
"timeLineIdx": 0
},
{
"timeLineName": "作者简介",
"timeLineIdx": 2
},
{
"timeLineName": "创作背景",
"timeLineIdx": 3
},
{
"timeLineName": "历代版本及传刻情况",
"timeLineIdx": 4
},
{
"timeLineName": "文献价值",
"timeLineIdx": 5
},
{
"timeLineName": "相关推荐",
"timeLineIdx": 6
},
{
"timeLineName": "文献目录",
"timeLineIdx": 1
}
]
根据timeLineIdx排序然后渲染至时间线
let newArr = JSON.parse(JSON.stringify(this.newdirectoryArr))
newArr.sort((a, b) => {
return a.timeLineIdx - b.timeLineIdx
})
this.newdirectoryArr = newArr
设置一个默认目录位置,从0开始,也就是第一个,根据点击的下标与值相匹配时显示对应class样式
newCurrentNum: 0, //当前目录
// 样式名切换
currentClass (index) {
return [this.newCurrentNum == index ? 'isActive' : 'noActive'];
},
两种情况
1.点击目录相应位置时,直接定位到对应位置,并且高亮当前目录
//目录选中样式
currentInfo (index) {
this.newCurrentNum = index;
// 添加锚点
let jump = document.querySelectorAll(".lit_item");
let total = jump[index].offsetTop;
let distance =
document.documentElement.scrollTop || document.body.scrollTop;
// 平滑滚动,时长500ms,每10ms一跳,共50跳
let step = total / 50;
if (total > distance) {
smoothDown();
} else {
let newTotal = distance - total;
step = newTotal / 50;
smoothUp();
}
function smoothDown () {
if (distance < total) {
distance += step;
document.body.scrollTop = distance;
document.documentElement.scrollTop = distance;
setTimeout(smoothDown, 10);
} else {
document.body.scrollTop = total;
document.documentElement.scrollTop = total;
}
}
function smoothUp () {
if (distance > total) {
distance -= step;
document.body.scrollTop = distance;
document.documentElement.scrollTop = distance;
setTimeout(smoothUp, 10);
} else {
document.body.scrollTop = total;
document.documentElement.scrollTop = total;
}
}
},
2.鼠标滚动页面浏览时,显示到相应目录内容时,高亮其目录
1.先在method中定义滚动事件
// 滚动事件
onScroll (e) {
let scrolled =
document.documentElement.scrollTop || document.body.scrollTop;
// if (scrolled > 470) {
// console.log(scrolled)
// this.currentNumber = 0;
// }
// 滚动选中锚点
let scrollItems = document.querySelectorAll('.lit_item');
for (let i = scrollItems.length - 1; i >= 0; i--) {
// 判断滚动条滚动距离是否大于当前滚动项可滚动距离
let scrolled = document.documentElement.scrollTop || document.body.scrollTop;
let judge = scrolled >= scrollItems[i].offsetTop - scrollItems[0].offsetTop
if (judge) {
this.newCurrentNum = i
break
}
}
},
2.在mounted中定义监听滚动事件
mounted: function () {
this.$nextTick(function () {
window.addEventListener("scroll", this.onScroll);
});
},
this.$nextTick:官方解释
将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。
它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
个人理解
等待DOM加载完成后再执行
---------------------------------