記錄一下使用vue.js封裝錨點組件的代碼。項目中存在固定頭部的情況。
主要思路為在組件初始化時,將錨點列表中的位置一次性獲取,在點擊錨點時,直接使用document.documentElement.scrollTop進(jìn)行定位。添加頁面滑動事件,在頁面滑動時判斷當(dāng)前頁面展示部分屬于哪個錨點,動態(tài)渲染錨點高亮。
完整組件地址:傳送門
// 分步滑動頁面進(jìn)行定位
byStepShow: function(scrollTop) {
let top = Math.abs(document.documentElement.scrollTop - scrollTop)
const $this = this
const animationCallback = function() {
top -= $this.stepHeight
if (top <= 0) {
document.documentElement.scrollTop = scrollTop
return
} else {
requestAnimationFrame(animationCallback)
if (document.documentElement.scrollTop > scrollTop) {
document.documentElement.scrollTop = document.documentElement.scrollTop - top
} else {
document.documentElement.scrollTop = document.documentElement.scrollTop + top
}
}
}
animationCallback()
},
// 滾動頁面時的監(jiān)聽回調(diào)函數(shù)
onScroll: function() {
if (this.anchorList.length === 0) {
return
}
if (this.anchorPosition.length === 0 || this.scrollAlwaysComputePosition) {
this.anchorList.forEach(anchor => {
const toElement = document.querySelector('#' + anchor.id)
if (toElement) {
this.anchorPosition.push({
id: anchor.id,
position: toElement.offsetTop + (this.fixedHeader ? -this.headerHeight : this.headerHeight)
})
}
})
}
// 因為頁面頭部信息是固定高度的,需要在瀏覽器滾動條滾動頁面時,加上頭部高度計算定位位置
const headerHeight = this.fixedHeader ? -this.headerHeight : this.headerHeight
let scrolled = document.documentElement.scrollTop || document.body.scrollTop
scrolled = Math.ceil(headerHeight + scrolled)
// 將錨點位置列表根據(jù)錨點位置排序
this.anchorPosition.sort(function(pre, next) { return pre.position - next.position })
// 根據(jù)頁面位置進(jìn)行當(dāng)前錨點高亮
for (let i = 0; i < this.anchorPosition.length - 1; i++) {
if (scrolled >= this.anchorPosition[i].position && scrolled < this.anchorPosition[i + 1].position) {
this.activeAnchor = this.anchorPosition[i].id
}
}
if (this.anchorPosition.length === 0) {
return
}
if (scrolled >= this.anchorPosition[this.anchorPosition.length - 1].position) {
this.activeAnchor = this.anchorPosition[this.anchorPosition.length - 1].id
}
}