导航菜单实现平滑切换页面

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>渐进式背景 · 内容切换</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    html,
    body {
      height: 100%;
      overflow: hidden;
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
    }

    .bg-layer {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: center/cover no-repeat;
      z-index: -1;
      opacity: 0;
      transition: opacity 0.5s ease;
    }

    .bg-layer.visible {
      opacity: 1;
    }

    .menu {
      position: fixed;
      top: 0;
      width: 100%;
      padding: 12px 0;
      background: rgba(255, 255, 255, 0.85);
      backdrop-filter: blur(4px);
      display: flex;
      justify-content: center;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
      z-index: 1000;
    }

    .menu a {
      margin: 0 20px;
      text-decoration: none;
      color: #333;
      padding: 6px 16px;
      border-radius: 20px;
      transition: all 0.3s;
    }

    .menu a.active,
    .menu a:hover {
      background: #ffcc00;
      color: #000;
    }

    main {
      position: absolute;
      top: 60px;
      width: 100%;
      height: calc(100% - 60px);
      display: flex;
      justify-content: center;
      align-items: center;
      padding: 20px;
    }

    .content-card {
      display: none;
      width: 100%;
      max-width: 700px;
      background: rgba(233, 233, 233, 0.16);
      backdrop-filter: blur(6px);
      border-radius: 16px;
      box-shadow: 0 6px 24px rgba(0, 0, 0, 0.12);
      padding: 32px;
      text-align: center;
      color: #333;
    }

    .content-card.active {
      display: block;
    }

    .content-card h2 {
      margin: 0 0 20px;
      font-size: 28px;
    }

    .content-card p {
      font-size: 18px;
      line-height: 1.6;
      margin-bottom: 25px;
    }

    .follow-tip {
      background: rgba(255, 240, 200, 0.6);
      border-left: 4px solid #ffaa00;
      padding: 12px;
      font-size: 16px;
      border-radius: 6px;
      margin-top: 20px;
    }
  </style>
</head>

<body>
  <div class="bg-layer visible" id="bgLayer"></div>

  <nav class="menu">
    <a href="#section1" class="active">首页</a>
    <a href="#section2">动态</a>
    <a href="#section3">关于</a>
  </nav>

  <main>
    <section id="section1" class="content-card active">
      <h2>欢迎来到我的空间</h2>
      <p>这里分享技术、生活与思考。内容持续更新,敬请期待!</p>
      <div class="follow-tip">🔔 别忘了关注我,获取最新内容推送!</div>
    </section>
    <section id="section2" class="content-card">
      <h2>最新动态</h2>
      <p>今天发布了新教程《前端性能优化实战》,点击主页查看。</p>
      <div class="follow-tip">📱 关注「ヤ鬧鬧o.」,不错过任何更新!</div>
    </section>
    <section id="section3" class="content-card">
      <h2>关于我</h2>
      <p>一名热爱代码与设计的开发者,致力于打造优雅的用户体验。</p>
      <div class="follow-tip">📧 联系我:example@email.com | 欢迎交流!</div>
    </section>
  </main>

  <script>
    const bgLayer = document.getElementById('bgLayer');
    const links = document.querySelectorAll('.menu a');
    const cards = document.querySelectorAll('.content-card');
    const highResCache = {};

    const bgConfig = {
      '#section1': { low: 'https://picsum.photos/32/18?blur=3&random=1', high: 'https://picsum.photos/1920/1080?blur=2&random=1' },
      '#section2': { low: 'https://picsum.photos/32/18?blur=3&random=2', high: 'https://picsum.photos/1920/1080?blur=2&random=2' },
      '#section3': { low: 'https://picsum.photos/32/18?blur=3&random=3', high: 'https://picsum.photos/1920/1080?blur=2&random=3' }
    };

    function loadBackground(hash) {
      const cfg = bgConfig[hash];
      if (!cfg) return;

      // 显示低清图
      bgLayer.style.backgroundImage = `url(${cfg.low})`;
      bgLayer.classList.remove('visible');
      requestAnimationFrame(() => bgLayer.classList.add('visible'));

      // 若高清已缓存,直接使用
      if (highResCache[hash]) {
        setTimeout(() => bgLayer.style.backgroundImage = `url(${highResCache[hash]})`, 100);
        return;
      }

      // 加载高清图
      const img = new Image();
      img.onload = () => {
        highResCache[hash] = cfg.high;
        bgLayer.style.backgroundImage = `url(${cfg.high})`;
      };
      img.src = cfg.high;
    }

    function updateView() {
      const hash = location.hash || '#section1';
      links.forEach(a => a.classList.toggle('active', a.getAttribute('href') === hash));
      cards.forEach(card => card.classList.toggle('active', `#${card.id}` === hash));
      loadBackground(hash);
    }

    links.forEach(a => a.addEventListener('click', e => {
      e.preventDefault();
      history.pushState(null, '', a.href);
      updateView();
    }));

    window.addEventListener('popstate', updateView);
    loadBackground('#section1'); // init
  </script>
</body>

</html>
相关推荐
bjzhang759 分钟前
使用HTML+CSS美化上传进度条展示
前端·css·html
何以解忧,唯有..15 分钟前
Vue 3 响应式核心:ref() 与 reactive() 的深入解析与实战
前端·javascript·vue.js
YWL21 分钟前
CSS变量与预处理器
前端·css
zzzzzz3101 小时前
看 react-bits,不要只看“酷炫”:一套阅读动画交互组件库的框架
javascript·react.js·动效
香芋芋圆9 小时前
AI 冲击内卷之下,普通前端如何破局?WebGIS—— 低门槛突围赛道
前端·javascript·人工智能·学习·职场发展
INS_KF10 小时前
【编程笔记】成员函数中两个 const 的区别(const Data &getData() const;)
前端·javascript·笔记
宿67410 小时前
vue3-async
前端·javascript·vue.js
excel11 小时前
Nuxt + Twin CSS 中宽度超过屏幕时底部出现空白的原因与解决方案
前端·javascript
一个游离的指针14 小时前
函数管道:消除深度嵌套调用
前端·javascript
柚yuzumi15 小时前
前端优化,从少触发一次开始:防抖与节流
前端·javascript