vue中实现锚点定位以及平滑滚动到指定位置
Vue锚点定位传统方式遇到的问题解决办法scrollTop或者scrollIntoView传统方式遇到的问题原生网页做锚点跳转一般使用id和a标签的href实现:<h1 id="title">title</h1><a href="#title">跳转到title</a>在Vue-router中,如果使用的是history模式,当点击超链接时,URL地
·
锚点定位
传统方式遇到的问题
原生网页做锚点跳转一般使用id和a标签的href实现:
<h1 id="title">title</h1>
<a href="#title">跳转到title</a>
在Vue-router中,如果使用的是history模式,当点击超链接时,URL地址会加上#title,导致hash值改变,导致需要多次点击返回才能返回到上一页面。
解决办法
scrollTop或者scrollIntoView
属性 | 说明 |
---|---|
scrollTop | 对象的最顶部到对象在当前窗口显示的范围内的顶边的距离。即在出现了纵向滚动条的情况下,滚动条拉动的距离。是指某个可滚动区块向下滚动的距离,比如向下滚动了10个像素,那么这个元素的scrollTop属性值就是10,这个属性的值是可读写的,且不需要设置position。 |
offsetTop | 则是元素的上边框与父元素的上边框的绝对距离,不能对其进行赋值 |
<!-- 跳转锚点 -->
<a href="javascript:void(0)" @click="goAnchor('production')">
<el-menu-item index="7" class="last-menu">作品</el-menu-item>
</a>
<!-- 跳转目的地 -->
<div class="production-box" id="production">
<span class="item-name">作品</span>
</div>
利用scrollTop
实现。
goAnchor(id) {
var anchor = document.getElementById(id);
// chrome
document.body.scrollTop = anchor.offsetTop;
// firefox
document.documentElement.scrollTop = anchor.offsetTop;
// safari
window.pageYOffset = anchor.offsetTop;
},
方法二:
goAnchor(id) {
var anchor = document.getElementById(id);
anchor.scrollIntoView();
},
平滑滚动到指定位置
<template>
<div>
<!-- 内容区域 -->
<div class="content">
<div>
content-0
</div>
<div>
content-1
</div>
<div>
content-2
</div>
<div>
content-3
</div>
<div>
content-4
</div>
</div>
<!-- 导航区域 -->
<ul class="navs">
<li :class="{active: active===0}">
content-0
</li>
<li :class="{active: active===1}">
content-1
</li>
<li :class="{active: active===2}">
content-2
</li>
<li :class="{active: active===3}">
content-3
</li>
<li :class="{active: active===4}">
content-4
</li>
</ul>
</div>
</template>
<script>
export default {
props: {},
data() {
return {
active: 0 // 当前激活的导航索引
}
},
methods: {}
}
</script>
<style scoped>
/* 内容区的样式 */
.content {
background-color: white;
width: 500px;
}
.content div {
width: 100%;
height: 600px;
font-size: 36px;
padding: 20px;
background-color: #7ec384;
}
.content div:nth-child(2n) {
background-color: #847ec3;
}
/* 导航栏的样式 */
.navs {
position: fixed;
top: 80px;
left: 700px;
background-color: #efefef;
}
.navs li {
padding: 0 20px;
line-height: 1.6;
font-size: 24px;
}
/* 当导航被点亮后改变颜色 */
.navs .active{
color: #847ec3;
background-color: #e2e2e2;
}
</style>
scrollTop与offsetTop
scrollTop
一个元素的 scrollTop 值是这个元素的顶部到视口可见内容(的顶部)的距离的度量。当一个元素的内容没有产生垂直方向的滚动条,那么它的 scrollTop 值为0。
offsetTop
HTMLElement.offsetTop 为只读属性,它返回当前元素相对于其 offsetParent 元素的顶部内边距的距离。
- position为fixed时,offsetParent为null,offsettop的值和top相等。此时元素是以视口来定位的。
- position非fixed,父级元素无定位(static)时,offsetParent为body。
- position非fixed,父级元素有定位时,offsetParent为最近的有定位的父级元素。
- body元素,offsetParent为null,offsettop为0(似乎是废话)。
监听滚动
当元素发生滚动时,会触发 scroll事件,我们就在 vue 的 mounted 钩子中添加监听好了,修改 vans.vue 文件
<script>
export default {
props: {},
data() {
return {
active: 0 // 当前激活的导航索引
}
},
mounted() {
// 监听滚动事件
window.addEventListener('scroll', this.onScroll)
},
destroy() {
// 必须移除监听器,不然当该vue组件被销毁了,监听器还在就会出错
window.removeEventListener('scroll', this.onScroll)
},
methods: {
onScroll() {
// 滚动监听器
}
}
}
</script>
现在我们开始写监听回调
// 滚动监听器
onScroll() {
// 获取所有锚点元素
const navContents = document.querySelectorAll('.content div')
// 所有锚点元素的 offsetTop
const offsetTopArr = []
navContents.forEach(item => {
offsetTopArr.push(item.offsetTop)
})
// 获取当前文档流的 scrollTop
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
// 定义当前点亮的导航下标
let navIndex = 0
for (let n = 0; n < offsetTopArr.length; n++) {
// 如果 scrollTop 大于等于第 n 个元素的 offsetTop 则说明 n-1 的内容已经完全不可见
// 那么此时导航索引就应该是 n 了
if (scrollTop >= offsetTopArr[n]) {
navIndex = n
}
}
// 把下标赋值给 vue 的 data
this.active = navIndex
}
更多推荐
已为社区贡献1条内容
所有评论(0)