滚动切换菜单
2018-11-16 本文已影响0人
easy_mark
主要用到了jq以及scrollTop和offsetHeight属性。首先菜单点击,页面定位用的肯定是锚点。右侧滚动到某一位置后。如何判断当前id是哪一个容器的呢?主要是用scrollTop和滚动后覆盖的容器高度加上offsetHeight去作比较实现的。下面见代码:
HTML结构:
<div class="app">
<div style="position:fixed;width:200px;height:600px;top:10px;left:10px;border:1px solid
#ddd">
<ul class='menu'>
<li v-for="item in menu">
<a class='menu-li' :href=item.id>{{item.text}}</a>
<ul class="c-menu">
<li v-for="subItem in item.subMenu"><a :href=subItem.id >{{subItem.text}}</a></li>
</ul>
</li
</ul>
</div>
<div class="items" id="菜单1">
菜单1
</div>
<div class="items" id="菜单1/菜单11">
菜单11
</div>
<div class="items" id="菜单1/菜单12">
菜单12
</div>
<div class="items" id="菜单1/菜单13">
菜单13
</div>
<div class="items" id="菜单2">
菜单2
</div>
<div class="items" id="菜单2/菜单21">
菜单21
</div>
<div class="items" id="菜单2/菜单22">
菜单22
</div>
<div class="items" id="菜单2/菜单23">
菜单23
</div>
<div class="items" id="菜单3">
菜单3
</div>
</div>
JS结构:
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.1.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
body{
margin:0;
}
.app{
overflow:hidden;
}
.active{
background:#ff0000;
}
.c-menu{
display:none;
}
.items{
width:calc(100% - 230px);
height:600px;
float:right;
border:1px solid red;
}
.db{
display:block
}
</style>
<script>
new Vue({
el: '.app',
data: {
menu:[{
id:'#菜单1',
text:'菜单1',
isShow:false,
subMenu:[{
id:'#菜单1/菜单11',
text:'菜单11',
parentId:'#菜单1',
},{
id:'#菜单1/菜单12',
text:'菜单12',
parentId:'#菜单1',
},{
id:'#菜单1/菜单13',
text:'菜单13',
parentId:'#菜单1',
},]
},{
id:'#菜单2',
text:'菜单2',
isShow:false,
subMenu:[{
id:'#菜单2/菜单21',
text:'菜单21',
parentId:'#菜单2',
},{
id:'#菜单2/菜单22',
text:'菜单22',
parentId:'#菜单2',
},{
id:'#菜单2/菜单23',
text:'菜单23',
parentId:'#菜单2',
},]
},{
id:'#菜单3',
text:'菜单3',
isShow:false,
subMenu:[]
}]
},
mounted(){
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
$('.menu-li').on("click",function(){
//去除所有的选中样式
$(".menu-li").parent().siblings().find('a').removeClass('active');
//为当前点击元素添加选中样式
$(this).addClass('active')
//隐藏所有元素的子菜单
$(this).parent().siblings().find('.c-menu').removeClass('db')
//显示当前元素子菜单
$(this).siblings('.c-menu').addClass('db')
})
var _this = this;
$(window).scroll(function(){
var top=document.documentElement.scrollTop || document.body.scrollTop;
var items = $('.items');
var sum = 0 ;
var thisObj ;
//遍历拿到滚动后视线内的id
for(var i=0;i<items.length;i++){
if(i==0){
sum = 0 ;
}else if(i==items.length-1){
thisObj = items[i]
break
}else {
sum = sum + items[i-1].offsetHeight
}
if(top-(sum+items[i].offsetHeight/2)<0){
thisObj = items[i]
break
}
}
//遍历去用jq操作左边侧边栏的展开状态
for(var j = 0 ;j<_this.menu.length;j++){
if('#'+thisObj.id == _this.menu[j].id){
$('.menu').find('.c-menu').removeClass('db')
$("[href='#"+thisObj.id+"']").siblings('.c-menu').addClass('db')
}
for(var k = 0; k<_this.menu[j].subMenu.length;k++){
if('#'+thisObj.id == _this.menu[j].subMenu[k].id){
$('.menu').find('.c-menu').removeClass('db')
$("[href='#"+thisObj.id+"']").parent().parent().addClass('db')
}
}
}
//追加选中状态
$("[href]").removeClass('active')
$("[href='#"+thisObj.id+"']").addClass('active')
})
})
},
methods: {
}
})
</script>