响应式Header导航栏源码分享

第一,首先创建基本的脚手架html代码,(如果本地有fontawesome-free-5.15.4-web的图标文件的,可以直接引入,如果没有那就使用图标代替搜索图标search-icon)
  1. <nav class="navbar">
  2. <div class="nav-container">
  3. <button class="menu-toggle">☰</button>
  4. <div class="nav-logo">
  5. <a href="#">
  6. 小言心
  7. </a>
  8. </div>
  9. <ul class="nav-menu">
  10. <li class="nav-item">
  11. <a href="#" class="nav-link active" data-index="0">首页</a>
  12. </li>
  13. <li class="nav-item">
  14. <a href="#" class="nav-link" data-index="1">发现</a>
  15. </li>
  16. <li class="nav-item">
  17. <a href="#" class="nav-link" data-index="2">等你来答</a>
  18. </li>
  19. <li class="nav-item">
  20. <a href="#" class="nav-link" data-index="3">会员</a>
  21. </li>
  22. <li class="nav-item">
  23. <a href="#" class="nav-link" data-index="4">Live</a>
  24. </li>
  25. <li class="nav-item">
  26. <a href="#" class="nav-link" data-index="5">书店</a>
  27. </li>
  28. </ul>
  29. <!-- 高亮条 -->
  30. <div class="highlight-bar"></div>
  31. <div class="search-container">
  32. <input type="text" class="search-box" placeholder="搜索小言心内容">
  33. <button class="search-icon " type="button" aria-label="搜索">
  34. <i class="fas fa-search"></i>
  35. </button>
  36. </div>
  37. <div class="nav-actions">
  38. <div class="dropdown">
  39. <div class="user-avatar">知</div>
  40. <div class="dropdown-content">
  41. <a href="#" class="dropdown-item">我的主页</a>
  42. <a href="#" class="dropdown-item">私信</a>
  43. <a href="#" class="dropdown-item">创作中心</a>
  44. <a href="#" class="dropdown-item">设置</a>
  45. <a href="#" class="dropdown-item">退出</a>
  46. </div>
  47. </div>
  48. <button class="nav-button">提问</button>
  49. </div>
  50. </div>
  51. </nav>
二,创建基本的style样式
  1. * {
  2. margin: 0;
  3. padding: 0;
  4. box-sizing: border-box;
  5. font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  6. }
  7. body {
  8. background-color: #f6f6f6;
  9. padding: 0;
  10. margin: 0;
  11. }
  12. .navbar {
  13. background-color: #ffffff;
  14. box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  15. position: sticky;
  16. top: 0;
  17. z-index: 1000;
  18. padding: 7px 16px;
  19. }
  20. .nav-container {
  21. max-width: 1200px;
  22. margin: 0 auto;
  23. display: flex;
  24. align-items: center;
  25. height: 52px;
  26. position: relative;
  27. }
  28. .nav-logo {
  29. margin-right: 20px;
  30. }
  31. .nav-logo a {
  32. display: flex;
  33. align-items: center;
  34. text-decoration: none;
  35. color: #0084ff;
  36. font-size: 24px;
  37. font-weight: 600;
  38. }
  39. .nav-menu {
  40. display: flex;
  41. list-style: none;
  42. margin-right: auto;
  43. position: relative;
  44. }
  45. .nav-item {
  46. margin-right: 20px;
  47. position: relative;
  48. }
  49. .nav-link {
  50. text-decoration: none; color: #373a40;
  51. font-size: 15px;
  52. padding: 16px 0;
  53. display: inline-block;
  54. position: relative;
  55. transition: color 0.3s;
  56. cursor: pointer;
  57. }
  58. .nav-link:hover {
  59. transition: 0.3s ease-in;
  60. font-weight: 600;
  61. }
  62. .nav-link.active {
  63. font-weight: 600;
  64. color: #191B1F;
  65. }
  66. /* 高亮条 */
  67. .highlight-bar {
  68. position: absolute;
  69. bottom: 0;
  70. height: 3px;
  71. background-color: #0084ff;
  72. transition: all 0.3s ease;
  73. border-radius: 1.5px;
  74. }
  75. .search-container {
  76. position: relative;
  77. margin-right: 20px;
  78. flex: 0 1 400px;
  79. }
  80. .search-box {
  81. width: 100%;
  82. padding: 8px 12px;
  83. border: 1px solid #ebebeb;
  84. border-radius: 20px;
  85. background-color: #f6f6f6;
  86. font-size: 14px;
  87. outline: none;
  88. transition: all 0.3s;
  89. }
  90. .search-box:focus {
  91. background-color: #fff;
  92. border-color: #0084ff;
  93. }
  94. .search-icon {
  95. color: #0077e6;
  96. border-bottom-right-radius: 9999px;
  97. border-top-right-radius: 9999px;
  98. position: absolute;
  99. right: -1px;
  100. background: transparent;
  101. border-bottom-left-radius: 0;
  102. border-color: transparent;
  103. border-top-left-radius: 0;
  104. margin-left: 12px;
  105. padding: 0 12px;
  106. cursor: pointer;
  107. display: inline-block;
  108. font-size: 14px;
  109. line-height: 32px;
  110. }
  111. .nav-actions {
  112. display: flex;
  113. align-items: center;
  114. }
  115. .nav-button {
  116. background-color: #0084ff;
  117. color: white;
  118. border: none;
  119. border-radius: 4px;
  120. padding: 8px 16px;
  121. font-size: 14px;
  122. cursor: pointer;
  123. margin-left: 16px;
  124. transition: background-color 0.3s;
  125. }
  126. .nav-button:hover {
  127. background-color: #0077e6;
  128. }
  129. .user-avatar {
  130. width: 30px;
  131. height: 30px;
  132. border-radius: 50%;
  133. background-color: #0084ff;
  134. color: white;
  135. display: flex;
  136. align-items: center;
  137. justify-content: center;
  138. font-weight: bold;
  139. margin-left: 16px;
  140. cursor: pointer;
  141. }
  142. /* 下拉菜单样式 */
  143. .dropdown {
  144. position: relative;
  145. }
  146. .dropdown-content {
  147. display: none;
  148. position: absolute;
  149. right: 0;
  150. top: 100%;
  151. background-color: white;
  152. min-width: 160px;
  153. box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
  154. border-radius: 4px;
  155. z-index: 999999;
  156. padding: 8px 0;
  157. }
  158. .dropdown:hover .dropdown-content {
  159. display: block;
  160. }
  161. .dropdown-item {
  162. padding: 10px 16px;
  163. text-decoration: none;
  164. display: block;
  165. color: #121212;
  166. font-size: 14px;
  167. transition: background-color 0.3s;
  168. }
  169. .dropdown-item:hover {
  170. background-color: #f6f6f6;
  171. }
  172. /* 移动端菜单按钮 */
  173. .menu-toggle {
  174. display: none;
  175. background: none;
  176. border: none;
  177. font-size: 20px;
  178. cursor: pointer;
  179. color: #8590a6;
  180. margin-right: 10px;
  181. }
  182. /* 响应式设计 - 平板端 */
  183. @media (max-width: 1024px) {
  184. .search-container {
  185. flex: 0 1 300px;
  186. }
  187. .nav-item {
  188. margin-right: 15px;
  189. }
  190. }
  191. /* 响应式设计 - 移动端 */
  192. @media (max-width: 768px) {
  193. .menu-toggle {
  194. display: block;
  195. }
  196. .nav-menu {
  197. display: none;
  198. position: absolute;
  199. top: 100%;
  200. left: 0;
  201. right: 0;
  202. background-color: white;
  203. flex-direction: column;
  204. box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  205. z-index: 1001;
  206. padding: 10px 0;
  207. }
  208. .nav-menu.active {
  209. display: flex;
  210. }
  211. .nav-item {
  212. margin: 0;
  213. width: 100%;
  214. }
  215. .nav-link {
  216. padding: 12px 16px;
  217. width: 100%;
  218. display: block;
  219. border-bottom: 1px solid #f0f0f0;
  220. }
  221. .nav-link:last-child {
  222. border-bottom: none;
  223. }
  224. .search-container {
  225. flex: 1;
  226. margin-right: 10px;
  227. order: 3;
  228. }
  229. .nav-logo {
  230. order: 2;
  231. /* margin-right: 0; */
  232. margin: 0 10px;
  233. flex: 0 0 auto;
  234. }
  235. .menu-toggle {
  236. order: 1;
  237. }
  238. .nav-actions {
  239. display: none;
  240. }
  241. .highlight-bar {
  242. display: none;
  243. }
  244. }
  245. /* 响应式设计 - 小屏幕移动端 */
  246. @media (max-width: 480px) {
  247. .navbar {
  248. padding: 0 10px;
  249. }
  250. .nav-logo a {
  251. font-size: 20px;
  252. }
  253. .search-container {
  254. margin-right: 5px;
  255. }
  256. }

四,点击active状态js代码标记
  1. document.addEventListener('DOMContentLoaded', function () {
  2. // 获取元素
  3. const navLinks = document.querySelectorAll('.nav-link');
  4. const highlightBar = document.querySelector('.highlight-bar');
  5. const menuToggle = document.querySelector('.menu-toggle');
  6. const navMenu = document.querySelector('.nav-menu');
  7. const navContainer = document.querySelector('.nav-container');
  8. // 防抖函数,优化窗口大小改变时的性能
  9. function debounce(func, wait) {
  10. let timeout;
  11. return function () {
  12. const context = this;
  13. const args = arguments;
  14. clearTimeout(timeout);
  15. timeout = setTimeout(() => {
  16. func.apply(context, args);
  17. }, wait);
  18. };
  19. }
  20. // 初始化高亮条位置
  21. function initHighlightBar() {
  22. const activeLink = document.querySelector('.nav-link.active');
  23. if (activeLink && window.innerWidth > 768) {
  24. moveHighlightBar(activeLink);
  25. } else {
  26. highlightBar.style.display = 'none';
  27. }
  28. }
  29. // 移动高亮条到指定元素
  30. function moveHighlightBar(targetElement) {
  31. if (window.innerWidth <= 768) {
  32. highlightBar.style.display = 'none';
  33. return;
  34. }
  35. highlightBar.style.display = 'block';
  36. const linkRect = targetElement.getBoundingClientRect();
  37. const containerRect = navContainer.getBoundingClientRect();
  38. highlightBar.style.width = linkRect.width + 'px';
  39. highlightBar.style.left = (linkRect.left - containerRect.left) + 'px';
  40. // 移除所有active类
  41. navLinks.forEach(link => {
  42. link.classList.remove('active');
  43. });
  44. // 添加active类到当前元素
  45. targetElement.classList.add('active');
  46. }
  47. // 为每个导航链接添加点击事件
  48. navLinks.forEach(link => {
  49. link.addEventListener('click', function (e) {
  50. e.preventDefault();
  51. moveHighlightBar(this);
  52. // 在移动端点击后关闭菜单
  53. if (window.innerWidth <= 768) {
  54. navMenu.classList.remove('active');
  55. }
  56. });
  57. });
  58. // 菜单切换按钮事件
  59. menuToggle.addEventListener('click', function () {
  60. navMenu.classList.toggle('active');
  61. });
  62. // 窗口大小改变时重新定位高亮条
  63. window.addEventListener('resize', debounce(function () {
  64. initHighlightBar();
  65. }, 100));
  66. // 点击页面其他区域关闭移动端菜单
  67. document.addEventListener('click', function (e) {
  68. if (window.innerWidth <= 768 &&
  69. !navMenu.contains(e.target) &&
  70. !menuToggle.contains(e.target) &&
  71. navMenu.classList.contains('active')) {
  72. navMenu.classList.remove('active');
  73. }
  74. });
  75. // 初始化
  76. initHighlightBar();
  77. });


返回顶部
  • 提示