原理
有点类似于轮播,整体的元素一直排列下去,假设有 5 个需要展示的全屏页面,那么高度是 500%,只是展示 100%,容器及容器内的页面取当前可视区高度,同时容器的父级元素 overflow 属性值设为 hidden,通过更改容器可视区的位置来实现全屏滚动效果。主要是响应鼠标事件,页面通过 CSS 的动画效果,进行移动。
大致结构
- html
<div id="container">
<div class="page">page1</div>
<div class="page">page2</div>
<div class="page">page3</div>
<!-- /...... -->
</div>
- css
.container {
width: 100vw;
height: 100vh;
overflow: hidden;
}
.page {
width: 100%;
height: 100vh;
}
主要是外层有个宽高为屏幕宽高的容器,里面的页面宽度为屏幕宽度,高度为屏幕高度,超出的页面被容器隐藏
切换动效
主要将容器的 transform: translateY(xxpx)
设置为负数,步长为屏幕高度,以实现全屏切换,如:transform: translateY(-100vh)
,向上移动一个屏幕的高度
- 伪代码
$(".toggleBtn").click(function(item) {
const pageNum = $(item).attr("pageNum"); // 要切换到第几个页面, 从1开始
$("#container").css({ transform: `translateY(-${(pageNum - 1) * 100}vh)` }); // 向上移动x个屏幕的高度
});
- 加上过渡动效
.container {
transition: all 0.6s ease-in-out;
}
这样当 translateY 发生改变时就会有过渡动效
鼠标滚动轴
以上只是实现了菜单点击的切换思路,接下来看看鼠标滚轴切换
- 思路
根据鼠标滚轴的滚动方向(上下)决定切换到上一页面还是下一页面
// 鼠标滚轴监听
window.addEventListener("mousewheel", e => {
console.log(e.wheelDelta);
if (e.wheelDelta < 0) {
// 向下
// 根据当前是第几个页面,计算 当前页面的translateY + 下一屏高度100vh 再取负数
} else {
// 向上
// 根据当前是第几个页面,计算 当前页面的translateY - 上一屏高度100vh 再取负数
}
});
vue代码示例
<template>
<div class="body">
<div class="nav">
<a
v-for="i in pageCount"
:href="`#panel${i}`"
:class="{ active: currentPage === i }"
:key="i"
@click="toggle(i)"
>页面{{ i }}</a
>
</div>
<div class="scroll" ref="scroll" :style="scrollStyle">
<div v-for="i in pageCount" :key="i" class="page">第{{ i }}个页面</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
pageCount: 6,
currentPage: 1
};
},
computed: {
scrollStyle() {
return { transform: `translateY(-${(this.currentPage - 1) * 100}vh)` };
}
},
methods: {
toggle(i) {
this.currentPage = i;
},
moushWheel(e) {
console.log(e.wheelDelta);
if (e.wheelDelta < 0) {
// 向下
this.currentPage =
this.currentPage + 1 < this.pageCount
? this.currentPage + 1
: this.pageCount;
} else {
// 向上
this.currentPage = this.currentPage - 1 > 0 ? this.currentPage - 1 : 1;
}
}
},
mounted() {
// 鼠标滚轴监听
window.addEventListener("mousewheel", this.moushWheel);
},
beforeDestroy() {
// 移除鼠标滚动轴监听
window.removeEventListener("mousewheel", this.moushWheel);
}
};
</script>
<style lang="scss" scoped>
.body {
width: 100vw;
height: 100vh;
overflow: hidden;
background: #3f3f3f;
}
.nav {
width: 100%;
height: 35px;
display: flex;
align-items: center;
position: fixed;
left: 0;
top: 0;
z-index: 999;
a {
flex-grow: 1;
text-align: center;
}
.active {
background: pink;
color: green;
font-weight: bold;
}
}
.scroll {
transition: all 0.6s ease-in-out;
.page {
height: 100vh;
text-align: center;
padding-top: 40vh;
color: #fff;
}
.page:nth-child(even) {
background: rgb(15, 19, 10);
}
}
</style>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。