这里很感谢 http://www.jb51.net/article/110325.htm 这篇文章带来的启发
但是我和他不同,网上的方法都是 这样计算滚动条距离窗口顶部的距离,注意是窗口,用的是document对象
// Chrome
document.body.scrollTop
// Firefox
document.documentElement.scrollTop
// Safari
window.pageYOffset
我这项目就无法正常这样使用了,首先我们vue项目有个总页面layout组件,左侧分 menu组件,最上方fixed了两块div,最后加上content页面内容给用户看的主界面,所有的页面都是这样渲染进layout__content里的 这就导致无法使用document对象来获取滚动条高度
具体的效果如图:
我调试发现,页面在某一块 上有css,滚动条就在这上面,所以,我这里使用的@scroll方法,
注意是@scroll 而不是scroll.native,
handleScroll (el) {
this.scrollTop = this.$refs.content.scrollTop
},
this.$refs.content.scrollTop 打印出来就是滚动条距离页面的距离
scrollTop 这个data属性,我通过props将其传到了子组件zhong,通过页面共同的入口router-view导入
当然这就将这个属性,所有页面都能接收到了,感觉不是很好,暂且先这样实现
回到我本身的展示页面,子组件 监听scrollTop
props: ['scrollTop'],
watch: {
scrollTop (val) {
this.onScroll()
this.pageTop = val
}
},
这里的pageTop 我这里做了一下赋值,因为尽量别直接在子组件改变props的值
created () {
this.$nextTick(() => {
this.pageTop = this.scrollTop
})
},
onScroll () {
let _article = document.querySelectorAll('.step-jump')
_article.forEach((item, index) => {
if (this.scrollTop >= item.offsetTop) {
this.activeStep = index
}
})
},
监听鼠标滚动事件,这样就可以实现了,当然我的页面html是这样的情况,以各个小组件拼接起来,夹杂着用来定位的相同class的div元素
现在来看一下step元素,如果你需要用到自定义的icon,需要加上这个属性,源码通过是否传入这个来判断是 icon 还是 text
点击事件方法 jump
jump (index) {
let that = this
this.activeStep = index
// 用 class="step-jump" 添加锚点
let jump = document.querySelectorAll('.step-jump')
let total = jump[index].offsetTop
console.log('纵坐标', total)
// this.$emit('viewScroll', total)
let distance = this.pageTop
// 平滑滚动,时长500ms,每10ms一跳,共50跳
let step = total / 50 >> 0
console.log(step, '222')
if (total > distance) {
smoothDown()
} else {
let newTotal = distance - total
step = newTotal / 50 >> 0
smoothUp()
}
function smoothDown () {
if (distance < total) {
distance += step
that.$emit('viewScroll', distance)
setTimeout(smoothDown, 10)
} else {
that.$emit('viewScroll', total)
}
}
function smoothUp () {
if (distance > total) {
distance -= step
that.$emit('viewScroll', distance)
setTimeout(smoothUp, 10)
} else {
that.$emit('viewScroll', total)
}
}
},
这里就是借鉴了网友的想法,每一小段一小段的跳,这样会导致视觉上是一个平滑的效果,而不是我点击了就突然scrollTop就突然下去或者上来,避免了很突兀的感觉。
有什么问题或建议,请直接提出来,谢谢哟
完善一下上面的代码,将多次emit事件删除,直接写入到父组件中!!!来判断
!!!! 其实上面这种实现还是有很大水分的,如果滚动条是相对于浏览器窗口的,其实直接document对象 判断scrollTop即可,另写一篇文章来重新书写vue scroll平滑滚动!最新的优化 可以看这个 ==========>>>>>>
https://blog.csdn.net/shentibeitaokong/article/details/81349819