其实有很多方法,主要是监听scroll,加上throttle节流
1.使用了getBoundingClientRect来计算元素的上下 距离视窗的距离来判断
changeAct() {
let basicH = 1.6 * this.basic + 1.15 * this.basic; //因为页面顶部有fixed,所以要扣去这段距离,用了rem所以加了个换算
let ar = document.getElementById('intro').getBoundingClientRect();
let br = document.getElementById('comment').getBoundingClientRect();
let cr = document.getElementById('actvity').getBoundingClientRect();
let aT = ar.top;
let aB = ar.bottom;
let bT = br.top;
let bB = br.bottom;
let cT = cr.top;
let cB = cr.bottom;
if (aT > basicH || aB - basicH > 20) { //之后就是根据top和bottom去判断距离了,然后去改成tab激活状态
this.changeCss('ii')
} else if (bT - basicH < 40 && bB - basicH > 20) {
this.changeCss('cc')
} else if (cT - basicH < 40 && cB - basicH > 20) {
this.changeCss('aa')
} else {
this.changeCss('', 'else')
}
},
2.在mounted和updated时计算几个锚点的高度
this.scrollTopDelimiters = []; //因为我就3个锚点,第一个就在首屏,所以也不需要计算, 最后一个计算和高度的和,因为需求需要变成空的激活标签
let br = this.$refs.comment.offsetTop-50;
let cr = this.$refs.actvity.offsetTop-50;
let dr = cr + this.$refs.actvity.offsetHeight;
this.scrollTopDelimiters = [br, cr, dr];
const $groups = this.$refs.groups;
const basicH = 1.6 * this.basic + 1.15 * this.basic;
const scrollTop = $groups.scrollTop + basicH;
const activeIndex = (() => {//之后就是进行scrollTop和元素offsetTop的比较进行return了
if (scrollTop > this.scrollTopDelimiters[this.scrollTopDelimiters.length - 1]) {
return 3;
} else if (scrollTop < this.scrollTopDelimiters[0]) {
return 0
} else {
let lowerBound = this.scrollTopDelimiters[0];
let upperBound = this.scrollTopDelimiters[1];
if (lowerBound <= scrollTop && scrollTop < upperBound) {
return 1
} else {
return 2
}
}
z
})();
this.activeIndex = activeIndex;
其实整个计算不难,只不过在逻辑思考上有点搞脑子..另外性能优化也是考虑的一点