vue写的pc端官网楼层跳转效果
前几天做了一个pc端官网,产品要求的效果是点击导航跳转到相应的位置,页面滚动的时候也要滚动在相应的位置。这个项目是用vue做的,和之前用jq直接操作dom还是有点区别的。直接上代码:header.vue顶部导航<template><div class="header_box"><div class="content">...
·
前几天做了一个pc端官网,产品要求的效果是点击导航跳转到相应的位置,页面滚动的时候也要滚动在相应的位置。这个项目是用vue做的,和之前用jq直接操作dom还是有点区别的。
直接上代码:
header.vue顶部导航
<template>
<div class="header_box">
<div class="content">
<!-- 左边 -->
<div class="log_box"></div>
<!-- 右边 -->
<div class="nav_box">
<ul id="ul">
<li v-for="(item,index) in navList" :key="item.id" :class="{active:selTab == index}" @click="tabFun(index)">{{item.text}}</li>
<li @click="goSelPage">定制方案</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
props:['navIndex'],
data(){
return{
selTab:this.navIndex,
navList:[
{ text:'首页', id:1 },
{ text:'服务流程', id:2 },
{ text:'应用方案', id:3},
{ text:'产品演示', id:4},
{ text:'安全防护',id:5 },
{ text:'关于我们', id:6},
],
}
},
methods: {
tabFun(i){ // 滚动导航的下标
this.selTab = i;
this.$emit('selectFun',i);
},
goSelPage(){ // 跳转定制方案
let token =window.localStorage.token;
if(token === 'null' || token === '' || token === undefined){
this.$router.push({
name:'login'
})
} else {
this.$router.push({
name:'selProgramme'
})
}
}
},
watch: {
navIndex(val){
this.selTab = val
}
},
mounted() {
},
}
</script>
<style lang="scss" scoped>
.header_box{
width: 100%;
height: 102px;
background: #164A9C;
position: fixed;
top: 0;
left: 0;
z-index: 10;
.content{
display: flex;
height: 100%;
// background: #f90;
.log_box{
width: 476px;
height: 100%;
background: url(../../assets/img/mian/logo.png) no-repeat;
background-size: 100% 61px;
margin-right: 30px;
background-position:center;
cursor: pointer;
}
.nav_box{
height: 100%;
// background: red;
ul{
display: flex;
li{
line-height: 102px;
font-size: 14px;
color: #ccc;
padding: 0 10px;
cursor: pointer;
}
.active{
border-bottom:2px solid #fff;
color: #fff;
}
}
}
}
}
</style>
index.vue首页
<template>
<div class="main_box">
<Header @selectFun="scrollTo" :navIndex="tabIndex"/>
<div class="main" id="scrollBox">
<!-- 轮播 -->
<div class="swipe_box loucen">
<el-carousel indicator-position="none" :height="bannerHeight+'px'">
<el-carousel-item v-for="(item,index) in carouselImg" :key="index">
<img :src="item.img" ref="bannerHeight" @load="imgLoad" class="img_bg" alt="">
<!-- <div :style="{background:'url('+item.img+')'}" class="img_bg"></div> -->
</el-carousel-item>
</el-carousel>
<!-- 登录按钮 -->
<div class="login_btn" ref="postTop" @click="toLog">
{{btnText}}
</div>
</div>
<!-- 流程服务 -->
<div class="fw_box loucen" >
<div class="content">
<img src="../../../assets/img/mian/index1.png" alt="">
</div>
</div>
<!-- 应用方案 -->
<div class="fa_box loucen" >
<div class="content">
<img src="../../../assets/img/mian/index2.png" alt="">
</div>
</div>
<!-- 应用场景 -->
<div class="cj_box loucen" >
<div class="content">
<img src="../../../assets/img/mian/index3.png" alt="">
</div>
</div>
<!-- 安全防护 -->
<div class="aq_box loucen" >
<div class="content">
<img src="../../../assets/img/mian/index4.png" alt="">
</div>
</div>
<!-- 关于我们 -->
<div class="wm_box loucen" >
<div class="content">
<img src="../../../assets/img/mian/index5.png" alt="">
</div>
</div>
</div>
</div>
</template>
<script>
import Header from '@/components/pc/header' // 头部
export default {
name:'index',
data() {
return {
tabIndex:0, // 导航下标
carouselImg:[
{
img:require('../../../assets/img/banner/banner1.png')
},
{
img:require('../../../assets/img/banner/banner2.png')
},
{
img:require('../../../assets/img/banner/banner3.png')
}
],
token:'',
bannerHeight:'', // banner高度
btnText:'登录查看定制方案'
}
},
methods: {
dataScroll () { // 滚动页面
const navContents= document.querySelectorAll('.loucen');
const offsetTopArr = [];
navContents.forEach(item => {
offsetTopArr.push(item.offsetTop)
})
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
let st = scrollTop;// + document.querySelector('.header_box').offsetHeight;
let navIndex = 0;
for(let i=0;i<offsetTopArr.length;i++){
if(st >= offsetTopArr[i]){
navIndex = i;
}
}
this.tabIndex = navIndex;
},
scrollTo(index){ // 点击导航
const targetOffsetTop = document.querySelector(`.loucen:nth-child(${index+1})`).offsetTop;
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
const STEP = 50;
if(scrollTop > targetOffsetTop){
// 往上滑
smoothUp()
} else {
// 往下滑
smoothDown()
}
function smoothDown(){ // 下滑函数
if(scrollTop < targetOffsetTop){
// 如果和目标相差距离大于等于 STEP 就跳 STEP
// 否则直接跳到目标点,目标是为了防止跳过了。
if (targetOffsetTop - scrollTop >= STEP) {
scrollTop += STEP
} else {
scrollTop = targetOffsetTop
}
let st = scrollTop ; // - document.querySelector('.header_box').offsetHeight
document.body.scrollTop = st;
document.documentElement.scrollTop = st;
// 关于 requestAnimationFrame 可以自己查一下,在这种场景下,相比 setInterval 性价比更高
requestAnimationFrame(smoothDown)
}
}
function smoothUp(){ // 上滑函数
if (scrollTop > targetOffsetTop) {
if (scrollTop - targetOffsetTop >= STEP) {
scrollTop -= STEP
} else {
scrollTop = targetOffsetTop
}
let st = scrollTop; // - document.querySelector('.header_box').offsetHeight
document.body.scrollTop = st;
document.documentElement.scrollTop = st;
requestAnimationFrame(smoothUp)
}
}
},
toLog(){ // 登录
if(this.token){
this.$router.push({
name:'selProgramme'
})
} else {
this.$router.push({
name:'login'
})
}
},
imgLoad() { // 页面渲染完成加载方法,确保屏幕中的图片的高度第一次渲染到页面
this.$nextTick(() => {
this.bannerHeight = this.$refs.bannerHeight[0].height;
this.$refs.postTop.style.top = this.bannerHeight / 2 + (this.$refs.postTop.offsetHeight * 2) + 'px'
})
}
},
mounted() {
window.addEventListener('scroll', this.dataScroll, false); // 监听页面滚动事件
this.imgLoad(); // 增加监听事件,当窗口发生变化的时候,得到此时图片的高,赋值给bannerHeight
window.addEventListener('resize', () => {
this.bannerHeight = this.$refs.bannerHeight[0].height;
this.$refs.postTop.style.top = this.bannerHeight / 2 + (this.$refs.postTop.offsetHeight * 2) + 'px'
this.imgLoad()
},false)
},
destroyed() {
window.removeEventListener('scroll', this.dataScroll)
},
components:{
Header,
},
created () {
this.token = window.localStorage.token;
this.btnText = this.token ? '查看定制方案' : '登录查看定制方案';
},
watch: {
},
}
</script>
<style lang="scss" scoped>
.active{
color: #ccc;
}
.main{
width: 100%;
position: relative;
.swipe_box{
width: 100%;
text-align: center;
position: relative;
.login_btn{
width: 184px;
height: 57px;
background: url('../../../assets/img/mian/login_btn.png') no-repeat;
background-size: cover;
position: absolute;
left: 400px;
// top: 300px;
z-index: 9;
cursor: pointer;
font-size: 18px;
text-align: center;
line-height: 57px;
color: #fff;
}
.img_bg{
width: 100%;
// height: inherit;
// min-height: 686px;
// min-width: 1400px;
// height: 100%;
// background-size: cover!important;
// background-position:center center!important;
// background-repeat: no-repeat!important;
}
}
.fw_box,.fa_box,.cj_box,.aq_box{
width: 100%;
height: 700px;
.content{
height: 100%;
text-align: center;
img{
width: 1200px;
height: 100%;
}
}
}
.fw_box{
background: #164A9C;
}
.fa_box{
}.cj_box{
}.aq_box{
background: #164A9C;
}.wm_box{
height: 2296px;
background: #F1F2F3;
.content{
height: 100%;
text-align: center;
img{
width: 1200px;
height: 100%;
}
}
}
}
</style>
更多推荐
所有评论(0)