效果图:
index.html(假设该页面要实现点击导航实现滚动功能)
<template>
<div>
<el-steps />
<div class="app-container-details">
<el-row type="flex" justify="center">
<el-col :span="23">
<div class="container-page-main">
<div class="section-item">
<el-card class="box-card">
<div slot="header">
<el-row class="item-title">
<i class="el-icon-tickets" style="padding: 10px;"> 用户注册</i>
</el-row>
<div style="height:300px;"></div>
</div>
</el-card>
</div>
<div class="section-item">
<el-card class="box-card">
<div slot="header">
<el-row class="item-title">
<i class="el-icon-tickets" style="padding: 10px;"> 详细报表</i>
</el-row>
</div>
2222222222222222222
<div style="height:300px;"></div>
</el-card>
</div>
<div class="section-item">
<el-card class="box-card">
<div slot="header">
<el-row class="item-title">
<i class="el-icon-tickets" style="padding: 10px;"> 税费情况</i>
</el-row>
</div>
<div class="main_content">
3333333333333
<div style="height:300px;"></div>
</div>
</el-card>
</div>
</div>
</el-col>
</el-row>
</div>
</div>
</template>
记得放上
<el-steps />
,我这里是放置与section的父级div平级,实际位置随意,因为右侧的导航定位是position:absolute
<style>
.app-container{
padding: 90px 100px 10px 15px; // 设置右侧的padding 100px,是为了给右侧导航条让位置
}
.section-item{
margin-bottom: 50px; // 让每个section之间上下间隔50px
}
</style>
<script>
import {elSteps} from '@/components'
export default {
name: 'aaaaaaaaaaa',
components: {
elSteps
},
components/index.js
export { default as elSteps} from './elSteps'
elSteps.vue
<template>
<el-steps
class="elSteps"
direction="vertical"
:active="active"
finish-status="wait"
process-status="finish"
align-center
>
<template v-for="(title,index) in titles">
<el-step
:key="index"
class="title"
:title="title"
icon="el-icon-s-opportunity"
@click.native="scrollToMove(index)"
></el-step>
</template>
</el-steps>
</template>
<script>
import { slowMove, arrayScroll } from '@/utils/scrollTo'
export default {
data() {
return {
active: 0,
titles: [],
}
},
mounted: function () {
const itemTitles = document.querySelectorAll('.item-title')
console.log('itemTitles:', itemTitles)
if (itemTitles && itemTitles.length > 0) {
itemTitles.forEach((itemTitle) => {
const is = itemTitle.querySelectorAll('i')
if (is && is.length > 0) {
this.titles.push(is[0].innerHTML)
}
})
}
// itemTitles[0].style.color = 'blue'
this.$nextTick(function () {
window.addEventListener('scroll', this.onScroll)
})
},
methods: {
scrollToMove(index) {
this.active = index
// item-title为index.html页面的各个section的class名字,通过class获取Dom节点,获取section的名字
const itemSection = document.querySelectorAll('.item-title')
// 获取需要滚动的距离
const total = itemSection[index].offsetTop
slowMove(total)
},
onScroll() {
this.active = arrayScroll('.item-title', 120)
},
},
}
</script>
<style>
.el-step.is-vertical .el-step__title {
font-size: 12px !important;
line-height: 25px !important;
display: flex;
}
.elSteps{
z-index: 999;
position: fixed;
min-height: 250px;
max-height: 400px;
right: 15px;
top: calc((100% - 200px) / 2);
}
.elSteps.el-step__icon {
background: #f5f7f9 !important;
}
</style>
utils/scrollTo.js
Math.easeInOutQuad = function(t, b, c, d) {
t /= d / 2
if (t < 1) {
return c / 2 * t * t + b
}
t--
return -c / 2 * (t * (t - 2) - 1) + b
}
// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
var requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
})()
/**
* Because it's so fucking difficult to detect the scrolling element, just move them all
* @param {number} amount
*/
function move(amount) {
document.documentElement.scrollTop = amount
document.body.parentNode.scrollTop = amount
document.body.scrollTop = amount
}
function position() {
return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
}
/**
* @param {number} to
* @param {number} duration
* @param {Function} callback
*/
export function scrollTo(to, duration, callback) {
const start = position()
const change = to - start
const increment = 20
let currentTime = 0
duration = (typeof (duration) === 'undefined') ? 500 : duration
var animateScroll = function() {
// increment the time
currentTime += increment
// find the value with the quadratic in-out easing function
var val = Math.easeInOutQuad(currentTime, start, change, duration)
// move the document.body
move(val)
// do the animation unless its over
if (currentTime < duration) {
requestAnimFrame(animateScroll)
} else {
if (callback && typeof (callback) === 'function') {
// the animation is done so lets callback
callback()
}
}
}
animateScroll()
}
export function slowMove(total){
let distance = document.documentElement.scrollTop || document.body.scrollTop /*|| window.pageYOffset*/
// 平滑滚动,时长500ms,每10ms一跳,共50跳
let step = 10;
if (total > distance) {
let newTotal = total - distance;
step = newTotal / 50;
smoothDown()
} else {
let newTotal = distance - total;
step = newTotal / 50
smoothUp()
}
function smoothDown () {
if (distance < total) {
distance += step
document.body.scrollTop = distance
document.documentElement.scrollTop = distance
window.pageYOffset = distance
setTimeout(smoothDown, 10)
} else {
document.body.scrollTop = total
document.documentElement.scrollTop = total
window.pageYOffset = total
}
}
function smoothUp () {
if (distance > total) {
distance -= step
document.body.scrollTop = distance
document.documentElement.scrollTop = distance
window.pageYOffset = distance
setTimeout(smoothUp, 10)
} else {
document.body.scrollTop = total
document.documentElement.scrollTop = total
window.pageYOffset = total
}
}
}
export function arrayScroll(className,num=0,color='blue') {
//页面滚动了的距离
let flag = 0;
let jump = document.querySelectorAll(className)
let height = document.documentElement.scrollTop || document.body.scrollTop /*|| window.pageYOffset*/
jump.forEach((j,index)=>{
let total = j.offsetTop+num
// j.style.color=''
if(index===0 && height<total){
flag = index
// j.style.color=color
}else
if(index===jump.length-1 && height>total){
flag = index
// j.style.color=color
}else if(index>0 && index<jump.length && jump[index-1].offsetTop+num < height && total > height){
flag = index
// j.style.color=color
}
})
return flag;
}
原理:
通过document.querySelectorAll(’.item-title’)获取到元素(item-title名字可根据实际需求进行变动),然后获取到元素的offsetTop,滚动到对应的位置