导航栏菜单指示器卡在第2个图标无法返回首个图标该如何修复?
导航菜单指示器开发问题修复
问题说明
开发菜单导航指示器效果时,出现如下异常:
- 图标上方添加文本框后,指示器始终卡在第2个图标位置无法正常移动
- 点击第3个图标可正常跳转回第1个图标,但点击第2个图标后无法返回第1个图标
- 新增文本框时会出现同类问题,指示器始终卡在最后一个添加的文本框对应位置
问题根因
- HTML结构不符合规范:将
.indicator直接放在ul标签内作为子元素,干扰了nth-child选择器的计数逻辑,同时DOCTYPE声明位置错误、body标签未闭合,存在基础语法问题 - 自定义
menu元素遮挡点击:menu的CSS设置了400px宽度,远超出单个导航项的70px宽度,且未设置点击穿透,导致超出部分遮挡了其他导航项的点击区域,点击第1个导航项时实际触发了第2个导航项的点击事件 - menu相关CSS选择器不匹配:写的是
span menu,但实际给menu加了.menu类,选择器优先级不匹配导致样式异常
修复方案
1. 修正HTML结构
将<!DOCTYPE html>放在文档最开头,补全body标签的闭合尖括号,把.indicator从ul内部移到ul同级的.navigation容器内:
<!DOCTYPE html> <html> <head> <title>Magic Menu Indicator</title> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <div class="navigation"> <ul> <li class="list active"> <a href="#"> <span class="icon"> <ion-icon name="earth-outline"></ion-icon> <menu class="menu"></menu> </span> <span class="text">Navigateur</span> </a> </li> <li class="list"> <a href="#"> <span class="icon"> <ion-icon name="home-outline"></ion-icon> <menu class="menu"></menu> </span> <span class="text">Profile</span> </a> </li> <li class="list"> <a href="#"> <span class="icon"> <ion-icon name="terminal-outline"></ion-icon> </span> <span class="text">Terminal</span> </a> </li> <li class="list"> <a href="#"> <span class="icon"> <ion-icon name="image-outline"></ion-icon> </span> <span class="text">Photos</span> </a> </li> <li class="list"> <a href="#"> <span class="icon"> <ion-icon name="settings-outline"></ion-icon> </span> <span class="text">Paramètres</span> </a> </li> </ul> <div class="indicator"></div> </div> <script> const list = document.querySelectorAll('.list'); const indicator = document.querySelector('.indicator'); function activelink(){ list.forEach((item) => item.classList.remove('active')); this.classList.add('active'); // 动态计算偏移位置 const index = Array.from(list).indexOf(this); indicator.style.transform = `translateX(calc(70px * ${index}))`; // 动态设置indicator背景色 const colors = ['#00a2ff', '#ae00ff', '#696563', '#ffe91f', '#ffaa00'] indicator.style.background = colors[index]; document.documentElement.style.setProperty('--new-color', colors[index]) } list.forEach((item) => item.addEventListener('click',activelink)); // 初始化默认激活第一项的位置 activelink.call(list[0]); </script> <script type="module" src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.esm.js"></script> <script nomodule src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.js"></script> </body> </html>
2. 修正CSS样式
给menu添加点击穿透属性,修正选择器匹配问题,调整偏移逻辑,删除原CSS中所有li:nth-child(x).active ~ .indicator相关的样式:
@import url('https://fonts.googleapis.com/css?family=Poppins:100,200,300,400,500,600,700,800,900'); * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', sans-serif; } :root { --clr: #222327; --new-color: #00a2ff; } body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background: var(--clr); } .navigation { position: relative; width: 400px; height: 70px; background: #fff; display: flex; justify-content: center; align-items: center; border-radius: 10px; } .navigation ul { display: flex; width: 350px; } .navigation ul li { position: relative; list-style: none; width: 70px; height: 70px; z-index: 1; } .navigation ul li a { position: relative; display: flex; Justify-content: center; align-items: center; flex-direction: column; width: 100%; text-align: center; font-weight: 500; } .navigation ul li a .icon { position: relative; display: block; line-height: 75px; font-size: 1.5em; text-align: center; transition: 0.5s; color: var(--clr); } .navigation ul li.active a .icon { transform: translateY(-32px); } .navigation ul li a .text { position: absolute; color: var(--clr); font-weight: 400; font-size: 0.75em; letter-spacing: 0.05em; transition: 0.5s; opacity: 0; transform: translateY(20px); } .navigation ul li.active a .text { opacity: 1; transform: translateY(-25px); } .indicator { position: absolute; top: -50%; width: 70px; height: 70px; background: #29fd53; border-radius: 50%; border: 6px solid var(--clr); transition: 0.5s; } .indicator::before { content: ''; position: absolute; top: 50%; left: -22px; width: 20px; height: 20px; background: transparent; border-top-right-radius: 20px; box-shadow: 1px -10px 0 0 var(--clr); } .indicator::after { content: ''; position: absolute; top: 50%; right: -22px; width: 20px; height: 20px; background: transparent; border-top-left-radius: 20px; box-shadow: -1px -10px 0 0 var(--clr); } /* 修正menu的基础样式 */ .navigation ul li a span .menu { transition: 0.3s; opacity: 0; transform: translateY(-135px); pointer-events: none; /* 禁止menu接收点击事件,避免遮挡其他导航项 */ position: absolute; /* 改为绝对定位,相对父级icon偏移 */ left: 50%; margin-left: -200px; /* 宽度400px,负margin居中 */ width: 400px; height: 70px; justify-content: center; align-items: center; border-radius: 10px; } /* 修正激活状态的menu样式 */ .navigation ul li.active a span .menu { background: var(--new-color); transition: 0.5s; opacity: 1; transform: translateY(-130px); }
内容的提问来源于stack exchange,提问作者Raytroll
相关产品推荐
相关产品推荐

