之前在网上看到一个特别骚气的页面阅读定位菜单,今天给大家分享一下原理,先看效果图:
这是我之前浏览联想官网上看到的一个效果图,觉得相当骚气。然后我把他的背景图扣下来,也做了一个,看看效果。
他的实现思路是:页面上放两个菜单,一个菜单是默认的,在页面的顶部。另一个菜单是默认隐藏的,当页面滚动默认菜单跑到屏幕以外时,这个转盘就会显示出来,并且会根据当前页面滚动阅读到的位置自动进行轮盘切换。当然这时我们也可以通过点击轮盘上的菜单进行快速跳转锚点去到我们想阅读的模块,如下图:
以下上代码:
HTML:
<ul class="fixd-menu" v-show="scrollMenu" :style="'transform:rotate('+MenuRotate+'deg)'"><li v-for="(item,index) in menu":key="item.code"@click="fixedMenu(index)":class="['fixd-menu-item','fixd'+item.code,fixeMenuNow===item.href?'fixd-now':'']"><a :href="'#'+item.href">{{item.title}}</a></li></ul>
css:
@keyframes menurun(){from{left: 0;}to{left: 1rem;}
}
.fixd-menu{position: fixed;top: calc(50% - 2.91rem);left: 1rem;width: 3.28rem;height: 3.28rem;background-image: url(../images/runner.png);background-size: 100%;background-position: center;z-index: 999;transition: all 1s;
}.fixd-menu .fixd-menu-item{font-size: .1rem;color: #fff;width: .95rem;height: .6rem;line-height: .6rem;text-align: center;background-position: center;background-size: 100%;background-repeat: no-repeat;position: absolute;
}
.fixd-menu .fixd-menu-item a{color: #fff;display: block;width: 100%;height: 100%;}.fixd-menu .fixd0{left: 1.15rem;top: .05rem;
}
.fixd-menu .fixd1{left: 1.928rem;top: .287rem;transform: rotate(37deg);
}
.fixd-menu .fixd2{left: 2.39rem;top: .95rem;transform: rotate(72deg);
}
.fixd-menu .fixd3{left: 2.39rem;top: 1.75rem;transform: rotate(109deg);
}
.fixd-menu .fixd4{left: 1.90rem;top: 2.38rem;transform: rotate(144deg);
}
.fixd-menu .fixd5{left: 1.16rem;top: 2.65rem;transform: rotate(180deg);
}
.fixd-menu .fixd6{left: .4rem;top: 2.38rem;transform: rotate(-144deg);
}
.fixd-menu .fixd7{left: -0.05rem;top: 1.73rem;transform: rotate(-109deg);
}
.fixd-menu .fixd8{left: -0.05rem;top: .94rem;transform: rotate(-72deg);
}
.fixd-menu .fixd9{left: .4rem;top: .299rem;transform: rotate(-37deg);
}
.fixd-now{background-image: url(../images/on_bg01.png);}
VueJS:
data:{menu:[{title:'首页',href:'app',code:0},{title:'服务流程',href:'service',code:1},{title:'关于我们',href:'AboutUs',code:2},{title:'我们的优势',href:'Advantages',code:3},{title:'工程案例',href:'Project',code:4},{title:'领导团队',href:'introduction',code:5},{title:'联系我们',href:'Contact',code:6}],DocumentTop:0,//页面上滚动scrollMenu:false,//滚动后显示的菜单fixeMenuNow:'',//当前悬浮菜单的选中MenuRotate:0//悬浮菜单旋转角度
},
methods:{scrolling(){//页面滚动监听this.DocumentTop = document.documentElement.scrollTop ||document.body.scrollTop ||window.pageYOffset;},fixedMenu(index){//转盘点击时轮盘旋转this.fixeMenuNow = window.location.hash.split('#')[1];this.MenuRotate = 0 - (index * 35);},autoScroll(){//页面滑动时转动轮盘var plate = document.getElementsByClassName('plate');/* 思路:(循环板块列表)当页面滚动等于阅读元素的offsetTop时,表示阅读到此位置了,轮盘的转动此时可通过阅读元素的id去菜单数组“menu”中查找 */var that = this;var readID = '';//当前阅读到的板块IDfor(var i=0;i<plate.length;i++){if(that.DocumentTop >= (plate[i].offsetTop-100) && that.DocumentTop < (plate[i].offsetTop + 100)){readID = plate[i].id;that.menu.map(function(item,index,arr){if(readID === item.href){that.MenuRotate = 0 -(item.code * 35)that.fixeMenuNow = item.hrefwindow.location.hash = "#"+item.href}}) }}}
},
mounted(){//页面挂在完成后给window监听滚动事件,并调用/执行我们定义的事件函数。window.addEventListener("scroll",this.scrolling);
},
watch: {//这里监听当记录页面滚动的变量发生改变时,调用相对应的函数DocumentTop(newValue, oldValue) {if(newValue >= 130){this.scrollMenu = truethis.fixeMenuNow = window.location.hash.split('#')[1];this.autoScroll()}if(newValue <= 50){this.scrollMenu = falsewindow.location.hash = "#app";}}},
,beforeDestroy(){//页面销毁时移除窗口滚动监听window.removeEventListener("scroll",this.scrolling)}
以上就是所有实现代码:
1、你可以根据自己的需求设置菜单内容,当然这个menu内容的href值一定要和页面的节点id相对应,因为我们时通过设置锚点来定位页面内容的。
2、css样式设置了多个fixd1、fixd2、fixd3、……,这是因为我们的轮盘格子只有这么多,并不会因为菜单变多而增加背景图片的格子。哈哈!如果你需要更多的菜单,可以让你的ui给你设计出多个背景图,然后根据菜单列表个数来决定你要哪张背景图,这样就可以实现动态背景图了。
3、代码和逻辑执行流程:进入页面,先给window绑定监听滚动事件,把回调函数替换成我们自己定义的函数。此时我们记录页面滚动距离的变量(this.DocumentTop)就有了初始值了。当this.DocumentTop发生了改变,我们vue的监听函数(watch)就会起到作用。
4、监听函数(watch)内的newValue要判断大于130的原因是。默认菜单和顶部的高度,我希望的是当滚动到默认菜单消失时轮盘才显示,如下图:(这里可以根据自己的需求来写)