You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CSS与JavaScript实现图片滚动至导航栏时停止上移效果

图片滚动贴导航栏停驻实现方案

核心逻辑:滚动时判断图片元素与固定导航栏的位置关系,当图片顶部触碰到导航栏底部时,切换为固定定位贴在导航栏下方;回滚到图片初始位置以上时,恢复原有定位,不影响向下滚动的正常浏览,同时保留原有的滚动缩放宽度效果。


1. 调整CSS样式

给目标图片容器新增吸顶状态的样式,处理固定定位后的水平居中问题,在原有styles.css基础上修改:

.mainSec {
  width: 100%;
  display: flex;
  justify-content: center;
}
#animatedDiv {
  background: url("https://media.tenor.com/images/34b16b199449136a845ea0300ff2cef3/raw")
    no-repeat;
  min-height: 200vh;
  width: 50%;
  position: absolute;
  margin-top: 20%;
  /* 可选:给宽度变化加微量过渡,避免快速滚动时卡顿跳变 */
  transition: width 0.1s linear;
}
/* 新增:吸顶状态样式 */
#animatedDiv.stuck {
  position: fixed;
  top: 10vh; /* 与导航栏高度完全一致,刚好贴在导航栏下沿 */
  margin-top: 0;
  left: 50%;
  transform: translateX(-50%); /* 固定定位后手动保持水平居中,匹配原有flex居中效果 */
}
#secondPage {
  background: url("https://www.downloadclipart.net/large/doraemon-png-free-download.png")
    no-repeat;
  display: block;
  width: 50%;
}

body {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: sans-serif;
}

nav {
  position: fixed;
  height: 10vh;
  background-color: rgb(12, 77, 151);
  display: flex;
  align-items: center;
  width: 100%;
  /* 给导航栏加z-index,避免固定后被其他元素遮挡 */
  z-index: 10;
}

/* 以下原有导航栏、logo、菜单样式全部保留不变 */
nav .logo a {
  color: white;
  font-size: 1.5rem;
  text-decoration: none;
  display: flex;
  text-align: center;
  margin: 0px 10px;
}
nav .nav-links {
  list-style: none;
  margin-left: auto;
}
.nav-links li {
  display: inline-block;
}

.nav-links .active {
  background-color: black;
  border: 2px solid black;
  border-radius: 10px;
}
nav .nav-links li a {
  color: white;
  text-decoration: none;
  font-size: 1rem;
  font-weight: 500;
  padding: 0px 10px;
}

@media screen and (max-width: 768px) {
  nav {
    position: relative;
    display: block;
  }
  /* 新增:移动端导航栏随页面滚动,禁用吸顶效果 */
  #animatedDiv.stuck {
    position: absolute;
    top: auto;
    left: auto;
    transform: none;
    margin-top: 20%;
  }
  /* 以下原有移动端样式全部保留不变 */
  .logo {
    height: 10vh;
    display: flex;
    align-items: center;
  }
  .logo a {
    text-align: center;
  }
  nav .menuIcon {
    position: absolute;
    cursor: pointer;
    top: 30%;
    right: 5%;
  }
  nav .menuIcon .line {
    width: 30px;
    margin: 5px 0px;
    height: 3px;
    background-color: white;
    position: relative;
  }
  nav .menuIcon .line:nth-child(1).open {
    transform: rotate(45deg);
    width: 40px;
    height: 5px;
    left: 0px;
    top: 16px;
    transition: all 1s ease;
  }
  nav .menuIcon .line:nth-child(2).open {
    opacity: 0;
  }
  nav .menuIcon .line:nth-child(3).open {
    transform: rotate(-45deg);
    width: 40px;
    height: 5px;
    transition: all 1s ease;
  }
  nav .nav-links {
    margin-top: -10px;
    padding: 0px;
    height: 90vh;
    width: 100%;
    background-color: rgb(12, 77, 151);
    display: flex;
    align-items: center;
    flex-direction: column;
    clip-path: circle(50px at 90% -10%);
    -webkit-clip-path: circle(50px at 90% -10%);
    transition: all 1s ease-out;
  }
  .nav-links li {
    margin: 40px 0px;
  }
  nav .nav-links.open {
    clip-path: circle(1000px at 90% -10%);
    -webkit-clip-path: circle(1000px at 90% -10%);
  }
  .nav-links li {
    opacity: 0;
  }
  .nav-links li a {
    font-size: 25px;
  }
  .nav-links li:nth-child(1) {
    transition: all 0.5s ease 0.2s;
  }
  .nav-links li:nth-child(2) {
    transition: all 0.5s ease 0.4s;
  }
  .nav-links li:nth-child(3) {
    transition: all 0.5s ease 0.6s;
  }
  .nav-links li:nth-child(4) {
    transition: all 0.5s ease 0.8s;
  }
  li.fade {
    opacity: 1;
  }
  .logo.close {
    visibility: hidden;
  }
}

2. 修改JS滚动逻辑

在原有宽度计算逻辑基础上,新增位置判断,控制吸顶类的添加移除,原有菜单交互代码完全不需要改动,修改后的index.js如下:

var aDiv = document.getElementById("animatedDiv");
// 提前计算固定值,避免每次滚动重复计算引发性能损耗
const navHeight = window.innerHeight * 0.1; // 对应导航栏10vh的高度
const initialDivOffsetTop = aDiv.offsetTop; // 图片容器初始状态距离页面顶部的距离

function onScroll() {
  var scrollVal = window.pageYOffset;

  // 保留原有的宽度缩放逻辑
  const targetWidth = 50 - (scrollVal * 100) / 1500;
  aDiv.style.width = targetWidth <= 10 ? "10%" : targetWidth + "%";

  // 新增吸顶判断
  if (scrollVal + navHeight >= initialDivOffsetTop) {
    // 图片顶部触碰到导航栏底部,添加吸顶类
    aDiv.classList.add("stuck");
  } else {
    // 回滚到图片初始位置以上,移除吸顶类恢复原状态
    aDiv.classList.remove("stuck");
  }
}

window.addEventListener(
  "scroll",
  function () {
    requestAnimationFrame(onScroll);
  },
  false
);

// 以下原有菜单交互代码完全保留,不需要修改
const menuIcon = document.querySelector(".menuIcon");
const menuIcons = document.querySelectorAll(".menuIcon .line");
const navLinks = document.querySelector(".nav-links");
const items = document.querySelectorAll(".nav-links li");
const logo = document.querySelector(".logo");
menuIcon.addEventListener("click", () => {
  navLinks.classList.toggle("open");
  logo.classList.toggle("close");
  items.forEach((item) => {
    item.classList.toggle("fade");
  });
  menuIcons.forEach((Icon) => {
    Icon.classList.toggle("open");
  });
});

const menu = document.querySelector(".nav-links");
const menuItems = document.querySelectorAll(".nav-links li");

menuItems.forEach((item) => {
  item.addEventListener("click", function () {
    menu.querySelector(".active").classList.remove("active");
    item.classList.add("active");
  });
});

补充说明

  • 如果后续调整导航栏高度,同步修改CSS中#animatedDiv.stuck的top值和JS中navHeight的计算逻辑,保持两个值一致即可,不会出现缝隙或者图片被导航栏遮挡的问题。
  • 导航栏的z-index:10可根据实际项目层级调整数值,避免固定定位的图片层级过高盖住导航栏。
  • 方案完全兼容原有宽度缩放动画、移动端汉堡菜单交互,不会产生冲突。

内容的提问来源于stack exchange,提问作者TechDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 16:18:20