动态Vanilla JS事件捕获问题:代码为何无法阻止链接跳转?
点击嵌套多层列表的A元素无法阻止页面跳转的问题排查
问题背景
尝试阻止嵌套在多层UL/LI结构中的A元素点击时的页面跳转,但编写的原生JS代码未生效,相关代码如下:
原JS代码
document.addEventListener("DOMContentLoaded", function(event) { let appendix_wrap = document.getElementById("wrap"); let hafigli_liv2 = appendix_wrap.querySelectorAll('ul.ul-submenu'); hafigli_liv2.forEach(ul_li_liv2 => { ul_li_liv2.addEventListener("click", (lk_liv2) => { const link_liv2 = lk_liv2.target.matches('ul.ul-submenu li.menu-item-has-children a'); this.preventDefault(); //evita che cambi pagina }); }); });
原HTML代码
<!DOCTYPE html> <html> <head> <title>prova js</title> </head> <body> <h1>js menu flush</h1> <ul id="wrap"> <li id="menu-item-658" class="menu-item-has-children ul-submenu-li"> <a title="tre" href="#">tre</a> <ul class="submenu-submenu"> <li id="menu-item-663" class="menu-item-has-children"> <a title="due" href="#">due</a> <ul class="ul-submenu"> <li id="menu-item-664" class="menu-item-664"> <a title="uno" href="#">uno</a> </ul> </ul> </li> </ul> </body> <p class="menu-item-description">Le maniglie perfette</p> </li> </body> </html>
错误原因分析
- HTML结构异常:存在多处标签未正确闭合问题,比如
<li id="menu-item-664">未闭合、<p>标签被放在<body>之外、<li id="menu-item-658">闭合位置错误,导致浏览器解析DOM时结构混乱,JS选择器无法正确定位目标元素。 - 事件绑定与逻辑错误:
- 箭头函数中的
this并非事件对象,调用this.preventDefault()无效,需使用事件参数lk_liv2调用该方法。 - 目标匹配选择器
'ul.ul-submenu li.menu-item-has-children a'与实际DOM结构不符:ul.ul-submenu下的<li>类名为menu-item-664,无menu-item-has-children类,无法匹配到目标A标签。 - 未做条件判断就执行阻止默认行为,即使点击的不是A标签也会触发,逻辑混乱。
- 箭头函数中的
修正方案
1. 修复HTML结构
确保所有标签正确闭合,DOM结构合法:
<!DOCTYPE html> <html> <head> <title>prova js</title> </head> <body> <h1>js menu flush</h1> <ul id="wrap"> <li id="menu-item-658" class="menu-item-has-children ul-submenu-li"> <a title="tre" href="#">tre</a> <ul class="submenu-submenu"> <li id="menu-item-663" class="menu-item-has-children"> <a title="due" href="#">due</a> <ul class="ul-submenu"> <li id="menu-item-664" class="menu-item-664"> <a title="uno" href="#">uno</a> </li> <!-- 闭合li标签 --> </ul> </li> <!-- 闭合li标签 --> </ul> </li> <!-- 闭合li标签 --> </ul> <p class="menu-item-description">Le maniglie perfette</p> <!-- 移到body内部 --> </body> </html>
2. 优化JS逻辑(使用事件委托)
直接在父元素#wrap上绑定点击事件,通过事件委托处理所有嵌套的A标签,逻辑更简洁且兼容动态添加的元素:
document.addEventListener("DOMContentLoaded", function() { const wrap = document.getElementById("wrap"); wrap.addEventListener("click", function(e) { // 判断点击目标是否是ul.ul-submenu下的A标签,可按需调整选择器范围 if (e.target.matches('ul.ul-submenu li a')) { e.preventDefault(); // 阻止页面跳转 console.log("点击目标A标签,已阻止跳转"); } }); });
若需阻止#wrap内所有嵌套A标签的跳转,可将选择器改为#wrap li a。
内容的提问来源于stack exchange,提问作者dulup
相关产品推荐
相关产品推荐

