【HTML】JavaScript 实现自适应响应式导航栏

发布于:2024-12-06 ⋅ 阅读:(146) ⋅ 点赞:(0)

1. 简介

利用 HTML 实现了一个简单的响应式导航栏,它能够根据屏幕大小调整其显示状态,并通过 JavaScript 实现收缩与折叠功能。

2. 实现效果

1. 当网页宽度大于 600px 时,导航栏状横向展开,态如下:

在这里插入图片描述

2. 当网页宽度小于 600px 时,导航栏横向收缩,状态如下:

在这里插入图片描述

3. 当网页宽度小于 600px 时,点击 ☰ 按钮,导航栏纵向展开:

在这里插入图片描述

3. 程序解析

3.1 文档类型声明
<!DOCTYPE html>

这是文档类型声明,它告诉浏览器该文档是一个 HTML5文档。

3.2 HTML根元素
<html lang="en">

<html>标签是所有其他 HTML元素的父元素。lang="en"属性指定了文档的语言是英语。

3.3 文档头部
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
/* 基本样式 */
body {
  margin: 0;
  font-family: Arial, sans-serif;
}
/* 导航栏样式 */
#navbar {
  background-color: #333;
  overflow: hidden;
}
#navbar a {
  float: left;
  display: block;
  color: white;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
}
/* 折叠按钮样式 */
.toggle-button {
  float: right;
  display: none;
  color: lightgreen;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 30px;
  cursor: pointer;
}
/* 响应式布局 - 当屏幕宽度小于600px时,将导航链接堆叠到按钮上方 */
@media screen and (max-width: 600px) {
  #navbar a, .toggle-button {
    float: none;
    display: block;
    text-align: left;
  }
  
  .links {
    display: none;
  }
}
</style>
</head>
  • <meta charset="UTF-8">: 设置文档的字符编码为 UTF-8。
  • <meta name="viewport" content="width=device-width, initial-scale=1.0">: 设置视口,确保在移动设备上正确显示。
  • <style>: 包含了 CSS样式,用于美化网页。
    • body样式:设置整个页面的边距和字体。
    • #navbar样式:定义导航栏的背景颜色和溢出隐藏。
    • #navbar a样式:定义导航链接的布局和外观。
    • .toggle-button样式:定义折叠按钮的外观,初始状态下不显示。
    • 媒体查询:当屏幕宽度小于 600px时,调整导航栏的布局,使链接堆叠在折叠按钮上方,并且默认不显示链接。
3.4 文档主体
<body>
<nav id="navbar">
  <button class="toggle-button" onclick="toggleMenu()"></button>
  <div class="links">
    <a href="#home">Home</a>
    <a href="#about">About</a>
    <a href="#contact">Contact</a>
  </div>
</nav>
<script>
function toggleMenu() {
  var links = document.querySelector('.links');
  if (links.style.display === 'block') {
    links.style.display = 'none';
  } else {
    links.style.display = 'block';
  }
}
// 当窗口大小改变时,如果屏幕宽度大于600px,则显示导航链接
window.onresize = function() {
  if (window.innerWidth > 600) {
    document.querySelector('.links').style.display = 'block';
  } else {
    document.querySelector('.links').style.display = 'none';
  }
};
</script>
</body>
  • <nav id="navbar">: 定义了一个导航栏,包含一个折叠按钮和三个导航链接。
  • <button class="toggle-button" onclick="toggleMenu()">☰</button>: 创建了一个按钮,当点击时会调用toggleMenu函数,用于切换导航链接的显示状态。
  • <div class="links">: 包含了三个<a>标签,每个标签代表一个导航链接。
  • <script>: 包含了JavaScript代码,用于处理导航栏的响应式行为。
    • toggleMenu函数:切换.links类的display属性,用于显示或隐藏导航链接。
    • window.onresize事件处理函数:当浏览器窗口大小改变时,根据窗口宽度决定是否显示导航链接。

这个网页的结构和样式都是响应式的,能够适应不同大小的屏幕。在屏幕宽度小于 600px时,导航链接会被隐藏,用户可以通过点击折叠按钮来显示或隐藏这些链接。

3.5 JavaScript 代码分析
3.5.1 toggleMenu 函数
function toggleMenu() {
  var links = document.querySelector('.links');
  if (links.style.display === 'block') {
    links.style.display = 'none';
  } else {
    links.style.display = 'block';
  }
}
  • document.querySelector('.links'): 使用querySelector方法选择类名为links的第一个元素。
  • if (links.style.display === 'block'): 检查links元素的display属性是否为'block'
  • 如果是'block',则将其设置为'none',隐藏导航链接。
  • 如果不是'block',则将其设置为'block',显示导航链接。
    这个函数被绑定到折叠按钮的onclick事件上,因此每次点击按钮时,都会切换导航链接的显示状态。
3.5.2 窗口大小改变事件处理
window.onresize = function() {
  if (window.innerWidth > 600) {
    document.querySelector('.links').style.display = 'block';
  } else {
    document.querySelector('.links').style.display = 'none';
  }
};
  • window.onresize: 这是一个事件处理器,当浏览器窗口大小改变时触发。
  • window.innerWidth: 获取浏览器窗口的内部宽度。
  • 如果窗口宽度大于 600px,则显示导航链接(.linksdisplay属性设置为'block')。
  • 如果窗口宽度小于或等于 600px,则隐藏导航链接(.linksdisplay属性设置为'none')。
    这段代码确保了在窗口大小改变时,导航栏能够适应屏幕宽度,实现响应式设计。

4. 整体交互流程

  1. 当页面加载时,如果屏幕宽度大于 600px,导航链接默认显示。
  2. 如果屏幕宽度小于 600px,导航链接默认隐藏,只显示折叠按钮。
  3. 用户点击折叠按钮时,toggleMenu函数被调用,导航链接的显示状态在显示和隐藏之间切换。
  4. 当用户调整浏览器窗口大小时,onresize事件处理器会根据当前窗口宽度自动显示或隐藏导航链接。

5. 注意事项

  • CSS 中使用了float属性来布局导航链接,这在现代 Web设计中可能不是最佳实践,因为flexboxgrid布局更为灵活和强大。
  • 在实际部署时,应确保折叠按钮的图标(☰)在不同设备和浏览器中能够正确显示。
  • 考虑到可访问性,应该为折叠按钮添加aria-expanded属性,以指示按钮的状态,并可能为键盘用户添加键盘事件监听。

6. 完整代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
/* 基本样式 */
body {
  margin: 0;
  font-family: Arial, sans-serif;
}

/* 导航栏样式 */
#navbar {
  background-color: #333;
  overflow: hidden;
}

#navbar a {
  float: left;
  display: block;
  color: white;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
}

/* 折叠按钮样式 */
.toggle-button {
  float: right;
  display: none;
  color: lightgreen;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 30px;
  cursor: pointer;
}

/* 响应式布局 - 当屏幕宽度小于600px时,将导航链接堆叠到按钮上方 */
@media screen and (max-width: 600px) {
  #navbar a, .toggle-button {
    float: none;
    display: block;
    text-align: left;
  }
  
  .links {
    display: none;
  }
}
</style>
</head>
<body>

<nav id="navbar">
  <button class="toggle-button" onclick="toggleMenu()"></button>
  <div class="links">
    <a href="#home">Home</a>
    <a href="#about">About</a>
    <a href="#contact">Contact</a>
  </div>
</nav>

<script>
function toggleMenu() {
  var links = document.querySelector('.links');
  if (links.style.display === 'block') {
    links.style.display = 'none';
  } else {
    links.style.display = 'block';
  }
}

// 当窗口大小改变时,如果屏幕宽度大于600px,则显示导航链接
window.onresize = function() {
  if (window.innerWidth > 600) {
    document.querySelector('.links').style.display = 'block';
  } else {
    document.querySelector('.links').style.display = 'none';
  }
};
</script>

</body>
</html>

Ext: FlexBox 布局实现

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
  /* 基本样式 */
  body {
    margin: 0;
    font-family: Arial, sans-serif;
  }

  /* 导航栏样式 */
  #navbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background-color: #333;
    padding: 10px;
  }

  /* 导航链接样式 */
  .links {
    display: flex;
    list-style: none;
  }

  .links li {
    padding: 0 15px;
  }

  .links a {
    text-decoration: none;
    color: white;
  }

  /* 折叠按钮样式 */
  .toggle-button {
    display: none;
    cursor: pointer;
    color: white;
  }

  /* 响应式设计 */
  @media (max-width: 600px) {
    .links {
      display: none;
      flex-direction: column;
      width: 100%;
    }

    .links.active {
      display: flex;
    }

    .links li {
      text-align: center;
      padding: 10px 0;
    }

    .toggle-button {
      display: block;
    }
  }
</style>
</head>
<body>

<nav id="navbar">
  <div class="toggle-button" onclick="toggleMenu()"></div>
  <ul class="links">
    <li><a href="#home">Home</a></li>
    <li><a href="#about">About</a></li>
    <li><a href="#services">Services</a></li>
    <li><a href="#contact">Contact</a></li>
  </ul>
</nav>

<script>
  function toggleMenu() {
    var links = document.querySelector('.links');
    links.classList.toggle('active');
  }

  window.onresize = function() {
    var links = document.querySelector('.links');
    if (window.innerWidth > 600) {
      links.classList.remove('active');
    } else {
      links.classList.add('active');
    }
  };
</script>

</body>
</html>

Ext: Grid 布局实现

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
  /* 基本样式 */
  body {
    margin: 0;
    font-family: Arial, sans-serif;
  }

  /* 导航栏样式 */
  #navbar {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    background-color: #333;
    padding: 10px;
  }

  /* 导航链接样式 */
  .links {
    display: flex;
    list-style: none;
    justify-content: space-around;
  }

  .links li {
    padding: 0 15px;
  }

  .links a {
    text-decoration: none;
    color: white;
  }

  /* 折叠按钮样式 */
  .toggle-button {
    display: none;
    cursor: pointer;
    color: white;
  }

  /* 响应式设计 */
  @media (max-width: 600px) {
    #navbar {
      grid-template-columns: 1fr;
      grid-template-rows: auto auto;
    }

    .links {
      display: none;
      flex-direction: column;
      width: 100%;
      grid-row: 2;
    }

    .links.active {
      display: flex;
    }

    .links li {
      text-align: center;
      padding: 10px 0;
    }

    .toggle-button {
      display: block;
      grid-row: 1;
    }
  }
</style>
</head>
<body>

<nav id="navbar">
  <div class="toggle-button" onclick="toggleMenu()"></div>
  <ul class="links">
    <li><a href="#home">Home</a></li>
    <li><a href="#about">About</a></li>
    <li><a href="#services">Services</a></li>
    <li><a href="#contact">Contact</a></li>
  </ul>
</nav>

<script>
  function toggleMenu() {
    var links = document.querySelector('.links');
    links.classList.toggle('active');
  }

  window.onresize = function() {
    var links = document.querySelector('.links');
    if (window.innerWidth > 600) {
      links.classList.remove('active');
    } else {
      links.classList.add('active');
    }
  };
</script>

</body>
</html>

网站公告

今日签到

点亮在社区的每一天
去签到