vue获取子组件高度
vue获取子组件高度this.loopHeight = this.$refs["vueHeader"].$refs["getHeader"].offsetHeight同理也可以获得子组件的数据和方法。需求描述就是官网的一个二级页内(锚点)导航,位置在轮播图下方。需要在轮播图看不见后,自动贴着一级导航(固定定位 position: fixed),固定定位在页头一级导航下面。...
·
vue获取子组件高度
this.loopHeight = this.$refs["vueHeader"].$refs["getHeader"].offsetHeight
同理也可以获得子组件的数据和方法。
需求描述
就是官网的一个二级页内(锚点)导航,位置在轮播图下方。
需要在轮播图看不见后,自动贴着一级导航(固定定位 position: fixed),固定定位在页头一级导航下面。
然后能看见轮播图的时候,二级导航还要下来,回到原位置,即取消固定定位。(position: static;)。
二级页内导航的下面,是高度不一的 part ,需要实现页面滚动到其对应部分内容可视的时候,对应的高亮二级导航样式。
项目背景
导航和轮播图都是 vue 子组件。
一级导航本身有监听页面滚动,是为了实现底色(背景色)的渐变。
代码
父组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<title></title>
<link href="css/common.css" rel="stylesheet">
<link href="css/swiper.min.css" rel="stylesheet">
<script src="js/vue.js"></script>
<script src="js/polyfill.min.js"></script>
<script src="js/vueComponents.js"></script>
<style>
div.navigation{
width: 100%;
height:75px;
line-height:75px;
box-sizing: border-box;
background: #fff;
color: #333;
border-bottom: 1px solid #d2d2d2;
}
.p-static{
position: static;
}
.p-fixed{
position: fixed;
top:64px;
z-index: 2;
}
a.nav2{
display:block;
width:240px;
position: relative;
margin-right:19px;
margin-left:19px;
box-sizing: border-box;
color: inherit;
font-weight: bold;
font-size: 15px;
text-align: center;
text-decoration: none;
}
.navigation a:after {
content: "";
display: inline-block;
width: 1px;
height: 40px;
background: #d2d2d2;
position: absolute;
top: 20px;
right: 0;
}
.navigation a:last-child:after{
background: #fff;
}
.active{
border-bottom: 5px solid #afd334;
}
div.part a{
display:block;
width: 100%;
height: 100%;
position: relative;
top: -139px;
}
div.part:target{
padding-top:139px;
}
</style>
</head>
<body>
<div id="root">
<vue-navbar></vue-navbar>
<vue-header ref="vueHeader"></vue-header>
<div class="navigation flex-box" :class=" positionType ? 'p-static' : 'p-fixed'">
<a class="nav2 parent1" href="#p1" @click="lighten($event)">行业痛点</a>
<a class="nav2 parent2" href="#p2" @click="lighten($event)">投资收益</a>
<a class="nav2 parent3" href="#p3" @click="lighten($event)">招募合伙人</a>
<a class="nav2 parent4" href="#p4" @click="lighten($event)">产品售前/售后服务</a>
</div>
<div class="part" id="p1" data-parent="parent1"><img src="img/attract/1.jpg" alt="图片"/></div>
<div class="part" id="p2" data-parent="parent2"><img src="img/attract/2.jpg" alt="图片"/></div>
<div class="part" id="p3" data-parent="parent3"><img src="img/attract/3.jpg" alt="图片"/></div>
<div class="part" id="p4" data-parent="parent4"><img src="img/attract/4.jpg" alt="图片"/></div>
<img src="img/attract/5.jpg" alt="图片"/>
<vue-footer></vue-footer>
</div>
<script src="js/jquery-3.1.1.min.js"></script>
<script src="js/swiper.min.js"></script>
<script>
new Vue({
el: "#root",
data: {
positionType:true,
loopHeight:100
},
methods: {
lighten: function (event) {
$(event.target).addClass("active").siblings().removeClass("active");
},
handleScroll2: function () {
var windowHeight = $(window).height(); //窗口高度
let windowsScrollTop = $(window).scrollTop();//距离顶部滚动
let windowsScrollTop2 = $(window).scrollTop() + 139;//距离顶部滚动 偏移一级导航+二级导航的高度共139
this.handleNav1(windowHeight,windowsScrollTop);
this.handleNav2(windowsScrollTop2);
},
handleNav1: function (windowHeight,windowsScrollTop) {
//当轮播不在可视区域时,将二级导航固定定位 fixed ,如轮播在可视区域,则取消固定定位。
let val = this.loopHeight - windowsScrollTop;
if (val < windowHeight && val > 0 ){
//轮播在可视区域
this.positionType=true;
}else{
//todo:有时二级页内导航下不去(定位不能回复static)positionType 一直是false
this.positionType=false;
}
},
handleNav2: function (windowsScrollTop) {
//二级导航的高亮问题 随页面滚动 当哪部分的内容可视,则将其对应的二级导航样式高亮
var dataAnimateEl = $('[data-parent]');
dataAnimateEl.each(function(){
let eleHeight = Math.floor($(this).height());//元素自身高度
var partEle = $(this);
let parent = partEle.attr("data-parent");
var pHeight = $(partEle).offset().top;//元素到顶部的高度
let maxHeight = pHeight + eleHeight;
if ( windowsScrollTop > pHeight && windowsScrollTop < maxHeight) {
//目标元素在可视区域
$("."+parent).addClass("active").siblings().removeClass("active");
}
});
}
},
mounted: function () {
//导航偏移 一级导航高度64
this.loopHeight = this.$refs["vueHeader"].$refs["getHeader"].offsetHeight - 64;//轮播图的高度
window.addEventListener('scroll', this.handleScroll2);
}
})
</script>
</body>
</html>
子组件
Vue.component('vue-navbar', {
data: function () {
return {
showNavbarItem:1,//默认第一项 首页 高亮
opacity_num: 1//导航透明度默认为0.1
}
},
methods: {
showNavbar: function (index){
if(index){
sessionStorage.setItem("showNavbarItem",index);
this.showNavbarItem = index
}else{
this.showNavbarItem = sessionStorage.getItem("showNavbarItem");
}
},
handleScroll: function () {
//随页面滚动距离 导航底色逐渐加深
this.winPos = $(window).scrollTop();//距离顶部滚动高度
if (this.winPos == 0) {
this.opacity_num = 1
} else if (this.winPos > 0 && this.winPos < 200 ) {
this.opacity_num = 3
} else if (this.winPos >= 200 && this.winPos < 300 ) {
this.opacity_num = 6
} else if (this.winPos >= 300) {
this.opacity_num = 10
}
}
},
mounted: function () {
window.addEventListener('scroll', this.handleScroll);
this.showNavbar();
},
template:`<div class="navbar" :class="'bg_opacity_'+opacity_num"><div class="logo"><img src="img/logo.png" alt="logo"></div><div class="nav" @click="showNavbar(1)"><a :class="showNavbarItem == 1 ? 'navbar-item-active' : ''" href="index.html">首页</a></div><div class="nav" @click="showNavbar(2)"><a :class="showNavbarItem == 2 ? 'navbar-item-active' : ''" href="about.html">关于我们</a></div><div class="nav" @click="showNavbar(3)"><a :class="showNavbarItem == 3 ? 'navbar-item-active' : ''" href="product.html">产品展示</a></div><div class="nav" @click="showNavbar(4)"><a :class="showNavbarItem == 4 ? 'navbar-item-active' : ''" href="cooperation.html">合作案例</a></div><div class="nav" @click="showNavbar(5)"><a :class="showNavbarItem == 5 ? 'navbar-item-active' : ''" href="attract.html">招商加盟</a></div><div class="nav" @click="showNavbar(6)"><a :class="showNavbarItem == 6 ? 'navbar-item-active' : ''" href="solution.html">解决方案</a></div></div>`
})
Vue.component('vue-header', {
data: function () {
return {
}
},
template: `<div class="header" ref="getHeader"><div id="index-swiper" class="swiper-container"><div class="swiper-wrapper"><div class="swiper-slide"><img alt="loop-img" src="img/loop/1.jpg"></div><div class="swiper-slide"><img alt="loop-img" src="img/loop/2.jpg"></div><div class="swiper-slide"><img alt="loop-img" src="img/loop/3.jpg"></div></div><div class="swiper-button-prev"></div><div class="swiper-button-next"></div></div></div>`,
mounted: function () {
//轮播
var indexSwiper = new Swiper('#index-swiper', {
slidesPerView: 1,
loop: true,
autoplay:true,
spaceBetween: 0,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
}
});
//鼠标覆盖停止自动切换
// indexSwiper.el.onmouseover = function () {
// indexSwiper.autoplay.stop();
// };
//
// indexSwiper.el.onmouseout = function () {
// indexSwiper.autoplay.start();
// }
}
})
Vue.component('vue-footer', {
data: function () {
return {
}
},
template: '<div class="footer"><img src="img/footer.jpg" alt="img"></div>'
})
总结
更多推荐
已为社区贡献2条内容
所有评论(0)