移动端导航子菜单IE11与iOS不显示问题求助
Hey there! 作为前端新手碰到这种跨浏览器兼容性问题真的太常见了,别着急,我帮你分析下问题所在,都是些小细节导致的~
问题根源分析
- IE11的API兼容性缺失:你的JS代码里用了
for...of循环和classList.replace()方法,这两个都是IE11完全不支持的API,直接导致JS在IE11里报错,子菜单逻辑根本跑不起来。 - 循环绑定事件的闭包陷阱:你用
var n循环绑定nav-link-1的点击事件,var没有块级作用域,所有事件处理函数都会共享同一个n变量,最终所有点击都会触发最后一个元素的逻辑,iOS浏览器里这个问题会更明显。 - iOS Safari的默认行为干扰:带
href的<a>标签点击会触发默认跳转行为,可能会打断子菜单的展开逻辑,尤其是href="#"这种,还会导致页面滚动,影响体验。
修复后的完整代码
HTML部分(无需修改)
<nav id="nav"> <div id="nav-menu-toggler"> <span>MENU</span> <div id="nav-toggler"></div> </div> <ul id="contenu-menu-1"> <li class="nav-item-1 trait-orange"> <a href="#" class="nav-link-1">LI1</a> <ul class="contenu-menu-2"> <li class="nav-item-2"><a href="li1.1.." class="nav-link-2">li1.1</a></li> <li class="nav-item-2"><a href="li1.2.." class="nav-link-2">li1.2</a></li> <li class="nav-item-2"><a href="li1.3.." class="nav-link-2">li1.3</a></li> </ul> <div class="afficher"></div> <!-- will display an arrow icon--> </li> <li class="nav-item-1 trait-orange"> <a href="#actualites" class="nav-link-1">LI2</a> </li> <li class="nav-item-1 trait-orange"> <a href="li3" class="nav-link-1">LI3</a> <ul class="contenu-menu-2"> <li class="nav-item-2"><a href="oenotourisme.php" class="nav-link-2">li3.1</a></li> <!-- ...and so on --> </ul> <div class="afficher"></div> </li> </ul> </nav>
CSS部分(无需修改)
#nav { display: flex; justify-content: center; flex-wrap: wrap; position: relative; min-height: 50px; width: 320px; z-index: 500; margin: 0 auto 5px auto; } #nav-menu-toggler { display: flex; flex-direction: row; justify-content: flex-end; align-items: center; width: 100%; height: 50px; cursor: pointer; font-size: 16px; font-family: "lato"; letter-spacing: 2px; } #nav-toggler { width: 28px; height: 28px; margin-left: 8px; background-image: url('../img/icone-menu.png'); background-size: cover; background-repeat: no-repeat; } #contenu-menu-1 { background-color:#3f372f; width: 100%; text-align: center; letter-spacing: 2px; list-style-type: none; visibility: hidden; opacity: 0; max-height: 0; overflow: hidden; transition: all 1s linear; } #contenu-menu-1.show { border-top: 1px solid rgba(255,255,255,.5); border-bottom: 1px solid rgba(255,255,255,.5); visibility: visible; opacity: 1; max-height: 800px; margin-bottom: 10px; } .contenu-menu-2 { list-style-type: none; width: 100%; visibility: hidden; opacity: 0; max-height: 0; overflow: hidden; transition: all 1s linear; } .contenu-menu-2.show { visibility: visible; opacity: 1; max-height: inherit; margin-bottom: 20px; } #contenu-menu-1 > .nav-item-1 { position: relative; display: flex; flex-wrap: wrap; justify-content: center; max-height: 300px; } #contenu-menu-1 > .nav-item-1:hover { border-radius: 0 0 3px 3px; } .contenu-menu-2 > .nav-item-2 { position: relative; display: flex; flex-wrap: wrap; justify-content: center; align-items: center; letter-spacing: initial; } #contenu-menu-1 .nav-item-1 > .nav-link-1 { text-decoration: none; color: white; font-weight: bold; font-size: 14px; width: 100%; padding: 10px 0; line-height: 30px; z-index: 200; } .contenu-menu-2 > .nav-item-2 .nav-link-2 { color: white; text-decoration: none; width: 100%; line-height: 25px; z-index: 300; } .contenu-menu-2 > .nav-item-2 .nav-link-2:hover { color: white; } #contenu-menu-1 > .nav-item-1.trait-orange::after { position: absolute; content: ""; height: 5px; width: 25px; background-color: rgb(211, 70, 30); bottom: -2.5px; z-index: 400; } .afficher-haut { position: absolute; right: 2px; top: 12px; display: block; height: 25px; width: 25px; background-size: cover; background-repeat: no-repeat; cursor: pointer; z-index: 100; background-image: url('../img/fleche-haut-menu.png'); } .afficher-bas { position: absolute; right: 2px; top: 12px; display: block; height: 25px; width: 25px; background-size: cover; background-repeat: no-repeat; cursor: pointer; z-index: 100; background-image: url('../img/fleche-bas-menu.png'); }
JavaScript部分(重点修复)
window.onload = function () { var bouton_menu = document.getElementById('nav-menu-toggler'); var contenu_menu_1 = document.getElementById('contenu-menu-1'); var contenu_menu_2 = document.getElementsByClassName('contenu-menu-2'); var afficher = document.getElementsByClassName('afficher'); var nav_links = document.getElementsByClassName('nav-link-1'); // 修复菜单按钮点击逻辑:替换for...of为传统for循环 bouton_menu.onclick = function () { // 处理箭头图标 for (var i = 0; i < afficher.length; i++) { var item = afficher[i]; if (item.classList.contains('afficher-haut')) { item.classList.remove('afficher-haut'); } else { item.classList.toggle('afficher-bas'); } } contenu_menu_1.classList.toggle('show'); // 关闭所有子菜单 for (var j = 0; j < contenu_menu_2.length; j++) { contenu_menu_2[j].classList.remove('show'); } }; // 修复子菜单点击逻辑:解决闭包问题+替换classList.replace+阻止默认跳转 for (var n = 0; n < nav_links.length; n++) { // 用立即执行函数保存当前循环的索引,避免闭包陷阱 (function(index) { nav_links[index].onclick = function (e) { // 阻止<a>标签的默认跳转行为,避免干扰子菜单 e.preventDefault(); // 仅当当前元素有子菜单时才执行逻辑 var subMenu = this.nextElementSibling; if (subMenu && subMenu.classList.contains('contenu-menu-2')) { subMenu.classList.toggle('show'); var afficherEl = subMenu.nextElementSibling; // 替换classList.replace为remove+add,兼容IE11 if (afficherEl.classList.contains('afficher-haut')) { afficherEl.classList.remove('afficher-haut'); afficherEl.classList.add('afficher-bas'); } else { afficherEl.classList.remove('afficher-bas'); afficherEl.classList.add('afficher-haut'); } } }; })(n); } };
关键修复说明
- 替换
for...of为传统for循环:IE11不支持for...of,改用兼容性更好的传统for循环遍历集合。 - 替换
classList.replace():IE11的classList没有replace方法,改用先移除旧类名、再添加新类名的方式实现相同效果。 - 解决闭包陷阱:用立即执行函数(IIFE)保存循环中的索引,确保每个点击事件绑定到对应的元素上,避免所有点击都指向最后一个元素。
- 阻止
<a>标签默认行为:添加e.preventDefault(),避免点击带href的链接时触发跳转,干扰子菜单展开逻辑,同时解决iOS Safari里的事件冲突。 - 增加子菜单存在判断:避免没有子菜单的项(比如LI2)点击时报错,增强代码健壮性。
测试建议
- 先在IE11里测试,确认JS不再报错,子菜单能正常展开/收起;
- 在iOS Safari里测试,点击带子菜单的链接时,子菜单正常显示,不会触发页面跳转或滚动;
- 顺便检查下所有子菜单的箭头图标切换是否正常。
内容的提问来源于stack exchange,提问作者raitxningu
相关产品推荐
相关产品推荐

