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

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>
相关推荐
luffy545911 小时前
css实现五星好评样式
前端·css·html
松涛和鸣12 小时前
DAY43 HTML Basics
linux·前端·网络·网络协议·tcp/ip·html
前端 贾公子12 小时前
剖析源码Vue项目结构 (一)
前端·javascript·vue.js
狂龙骄子12 小时前
jQuery表单验证插件全攻略
前端·javascript·jquery·jquery表单验证
十铭忘12 小时前
Vue3实现Pixso中的钢笔工具
开发语言·javascript·vue
局i12 小时前
【无标题】
前端·javascript·vue.js
前端小L13 小时前
双指针专题(四):像毛毛虫一样伸缩——「长度最小的子数组」
javascript·算法·双指针与滑动窗口
谢尔登13 小时前
Vue3 应用实例创建及页面渲染底层原理
javascript·vue.js·ecmascript
小笔学长13 小时前
XMLHttpRequest 对象:传统的网络请求方式
javascript·xmlhttprequest·前端开发·网络请求实战·跨域问题解决