vue项目中使用锚点
背景
如果页面有多个平级状态的内容,一般用tab显示。但是平级内容很多的话,使用tabs就不合适了。
需求
将同级状态标题以按钮形式排列,当点击标题按钮,页面相应内容自动定位滚动到顶部,就是所谓的锚点。
技术栈
vue2.x项目使用element-ui框架
实现
当然css也可以实现锚点功能,但是体验没有那么好。
可以使用dom元素的scrollIntoView()方法将元素滚动到浏览器窗口的可视区域
document.getElementById('id-name').scrollIntoView()
alignToTop | [可选],目前之前这个参数得到了良好的支持 |
true | 元素的顶部将对齐到可滚动祖先的可见区域的顶部。对应于scrollIntoViewOptions: {block: "start", inline: "nearest"}。这是默认值 |
false | 元素的底部将与可滚动祖先的可见区域的底部对齐。对应于scrollIntoViewOptions: {block: "end", inline: "nearest"}。 |
scrollIntoViewOptions | [可选],目前这个参数浏览器对它的支持并不好,可以查看下文兼容性详情 |
behavior | [可选]定义过渡动画。"auto","instant"或"smooth"。默认为"auto"。 |
block | [可选] "start","center","end"或"nearest"。默认为"center"。 |
inline | [可选] "start","center","end"或"nearest"。默认为"nearest"。 |
注意
- 容器必须设置可滚动;
- 不支持
"smooth"
行为或"center"
选项。
完整demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<link rel="stylesheet" href="./scrollIntoView.css">
</head>
<body>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<div id="app">
<ul class="btn-wrapper">
<li v-for="(item, index) in list" :key="index" class="item-btn" @click="clickItemBtn(index)">{{item}}</li>
</ul>
<div class="content">
<section v-for="(con, i) in list" :ref="`conRef${i}`" :key="i" class="item-content">
{{ con }}
</section>
</div>
</div>
<script>
const creatArray = (length) => Array.from(new Array(length), (val, i) => `item${i + 1}`)
new Vue({
el: '#app',
data: {
list: creatArray(9),
},
methods: {
clickItemBtn(index) /* 点击按钮触发 */ {
const [el] = this.$refs[`conRef${index}`]
el.scrollIntoView({
behavior: 'smooth'
})
}
}
})
</script>
</body>
</html>
样式
查看样式代码
/* scrollIntoView.css */
ul {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
.btn-wrapper {
margin-bottom: 20px;
}
.btn-wrapper .item-btn {
display: inline-block;
padding: 0 10px;
margin: 0 5px;
border: 1px solid skyblue;
border-radius: 4px;
cursor: pointer;
}
.btn-wrapper .item-btn:hover {
color: skyblue;
}
.content {
overflow-y: auto;
}
.content .item-content {
height: 250px;
margin-bottom: 20px;
background: #eee;
}