如何确保导航栏<li>元素点击时正确跳转已认证用户至Dashboard页面?
问题:账户图标点击行为不一致
已认证用户点击账户图标边缘时,能正确跳转至Dashboard页面;但点击图标中间区域时,却跳转至Login页面,不符合预期行为。
相关代码片段
index.ejs 页面代码
<header class="header nav-open"> <a href="/"> <img class="logo" src="img/NAMO.png" alt="NAMO logo"/> </a> <nav class="main-nav"> <ul class="main-nav-list"> <li> <a class="main-nav-link underline" href="/">Home</a> </li> <li> <a class="main-nav-link underline" href="#meals">About Us</a> </li> <li> <a class="main-nav-link underline" href="#blog">Blog</a> </li> <li> <a class="main-nav-link" data-action="toggle-cart"> <i class="fa-solid fa-cart-shopping"></i> <span class="cart-number"></span> </a> </li> <li id="account-icon-container"> <a id="account-icon" class="main-nav-link" href="/login"> <ion-icon name="person" class="profile-icon"></ion-icon> </a> </li> </ul> </nav> </header>
JavaScript 事件处理代码
document.addEventListener("DOMContentLoaded", () => { const personLi = document.getElementById("account-icon-container"); const personBtn = document.getElementById("account-icon"); const updateHref = async () => { try { const response = await fetch("/api/check-auth"); const authData = await response.json(); if (authData.isAuthenticated) { personBtn.href = "/dashboard"; } else { personBtn.href = "/login"; } } catch (error) { console.error("Error checking authentication status:", error); personBtn.href = "/login"; } }; if (personLi) { personLi.addEventListener("click", async event => { event.preventDefault(); await updateHref(); window.location.href = personBtn.href; }); } if (personBtn) { personBtn.addEventListener("click", event => { event.preventDefault(); }); } });
问题根源
- 初始化未同步链接:页面加载完成后,未主动调用
updateHref更新账户图标的跳转链接,仅在点击<li>边缘区域时才会触发认证状态检查并设置正确href。 - 事件逻辑冲突:点击
<a>图标区域时,代码仅阻止了默认跳转,但未同步执行认证检查和跳转逻辑,导致实际使用了<a>标签初始的默认href="/login"(或因事件冒泡/执行顺序问题,未触发<li>的点击处理逻辑)。
修复方案
方案1:初始化同步链接,移除冗余事件
页面加载时立即更新跳转链接,让<a>标签的默认跳转行为直接生效,无需额外事件监听:
document.addEventListener("DOMContentLoaded", async () => { const personBtn = document.getElementById("account-icon"); const updateHref = async () => { try { const response = await fetch("/api/check-auth"); const authData = await response.json(); personBtn.href = authData.isAuthenticated ? "/dashboard" : "/login"; } catch (error) { console.error("Error checking authentication status:", error); personBtn.href = "/login"; } }; // 页面加载完成后立刻初始化正确链接 await updateHref(); });
方案2:统一事件处理逻辑
保留<li>的点击区域支持,移除<a>的单独事件监听,确保点击任何区域都执行相同的认证检查和跳转:
document.addEventListener("DOMContentLoaded", () => { const personLi = document.getElementById("account-icon-container"); const personBtn = document.getElementById("account-icon"); const updateHref = async () => { try { const response = await fetch("/api/check-auth"); const authData = await response.json(); personBtn.href = authData.isAuthenticated ? "/dashboard" : "/login"; } catch (error) { console.error("Error checking authentication status:", error); personBtn.href = "/login"; } }; if (personLi) { personLi.addEventListener("click", async event => { event.preventDefault(); await updateHref(); window.location.href = personBtn.href; }); } });
额外优化(可选)
调整CSS让<a>标签覆盖整个<li>区域,彻底消除点击边缘和中间的差异:
#account-icon-container { padding: 0; } #account-icon { display: block; width: 100%; height: 100%; }
内容的提问来源于stack exchange,提问作者BrainDebugger
相关产品推荐
相关产品推荐

