基于scroll的吸顶效果

时间:2023-03-09 09:24:48
基于scroll的吸顶效果

本次要实现的是一种常见的网页效果,如下:

基于scroll的吸顶效果

页面由头部,导航,主体内容三部分组成,当页面发生滚动时,头部逐渐隐藏,导航部分向上移动,直到导航部分距离浏览器顶部为零时,导航部分固定不动,保持吸顶效果,如下所示:

基于scroll的吸顶效果

我们分三步实现上面的效果。

首先是页面的基础结构,为了简化操作,将头部、导航部分和主体内容部分全部用图片表示。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
list-style: none;
border:none
}
img{
vertical-align: top;
width: 100%;
} section{
width: 70%;
margin: 0 auto;
} </style>
</head>
<body>
<header id="head">
<img src="data:images/top.png" alt="">
</header>
<nav id="nav">
<img src="data:images/nav.png" alt="">
</nav>
<section>
<img src="data:images/body01.png" alt="">
<img src="data:images/body02.png" alt="">
</section>
</body>
</html>

此时,一个基本的页面效果已经出来了,我们再来做一个提前准备,就是监听滚动事件,所以需要用到上一篇所封装的方法和之前用的根据id获取元素方法:

<script>
function scroll() {
if(window.pageYOffset !== null){
return {
top: window.pageYOffset,
left: window.pageXOffset
}
}else if(document.compatMode === "CSS1Compat"){ // W3C
return {
top: document.documentElement.scrollTop,
left: document.documentElement.scrollLeft
}
}else{
return {
top: document.body.scrollTop,
left: document.body.scrollLeft
}
}
}
function $(id) {
  return typeof id === "string" ? document.getElementById(id) : null;
  }</script>

至此,所有的准备都完成了,我们再来分析理想的效果:当浏览器发生滚动时,页面向上卷起,直到顶部完全卷起,即浏览器的卷起部分等于导航部分最初距离顶部边缘的距离,此时,吸顶的部分即导航部分位于浏览器顶部,继续滚动时,主体部分发生了滚动,但导航部分的位置不再发生变化:

1,找到临界位置,卷起高度==初始化时导航部分距离浏览器顶部的高度

2,赋予导航部分吸顶效果:position:fixed

3,卷起高度变大时,继续吸顶,卷起高度变小时,取消吸顶

根据上面的分析,我们前面的基础上继续完善代码:

<style>
.nav{
position: fixed;
left: 0;
top:0;
width: 100%;
} </style> <script>
window.onload = function () {
// 1. 求出offsetHeight
var nav_top_height = $("nav").offsetTop; // 2. 监听窗口滚动
window.onscroll = function () {
var scroll_top_height = scroll().top;
console.log(scroll_top_height); // 2.1 判断
if(scroll_top_height >= nav_top_height){
$("nav").className = "nav";
}else {
$("nav").className = "";
}
}
}
</script>

这样,简易的吸顶效果就实现了,完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
list-style: none;
border:none
}
img{
vertical-align: top;
width: 100%;
} section{
width: 70%;
margin: 0 auto;
} .nav{
position: fixed;
left: 0;
top:0;
width: 100%;
} </style>
</head>
<body>
<header id="head">
<img src="data:images/top.png" alt="">
</header>
<nav id="nav">
<img src="data:images/nav.png" alt="">
</nav>
<section>
<img src="data:images/body01.png" alt="">
<img src="data:images/body02.png" alt="">
</section> <script>
function scroll() {
if(window.pageYOffset !== null){
return {
top: window.pageYOffset,
left: window.pageXOffset
}
}else if(document.compatMode === "CSS1Compat"){ // W3C
return {
top: document.documentElement.scrollTop,
left: document.documentElement.scrollLeft
}
}else{
return {
top: document.body.scrollTop,
left: document.body.scrollLeft
}
}
}
function $(id) {
  return typeof id === "string" ? document.getElementById(id) : null;
  }
window.onload = function () {
// 1. 求出offsetHeight
var nav_top_height = $("nav").offsetTop; // 2. 监听窗口滚动
window.onscroll = function () {
var scroll_top_height = scroll().top;
console.log(scroll_top_height); // 2.1 判断
if(scroll_top_height >= nav_top_height){
$("nav").className = "nav";
}else {
$("nav").className = "";
}
}
}
</script>
</body>
</html>

完整详细代码下载:点这里