如何让jQuery的.nav点击事件仅在非.showSite链接元素触发?
问题:点击导航内链接时不触发父元素的点击事件
现有HTML结构
<ul class="nav"> <li class="header">Sites</li> <li><a href="#" class="showSite" >Site A</a></li> <li><a href="#" class="showSite" >Site B</a></li> </ul>
原jQuery代码
$("body").on('click', '.nav', function( ) { console.log ( 'nav clicked' ) // other code // })
问题描述
点击.nav元素时,上述代码会正常执行,但我不希望点击其中的.showSite链接时触发这段代码。测试发现,即使点击链接,this输出的始终是.nav元素,而且.showSite的专属点击事件已经正常运行,只是要避免.nav的事件在此时触发。
自行尝试的解法
$("body").on('click', '.nav', function(e) { console.log ( 'nav clicked' ) if ( $(e.target).attr('class') == 'showSite' ) return false // other code // })
更可靠的优化方案
你的思路方向是对的,但直接判断class属性完全等于showSite有局限性——如果后续给链接添加其他class,这个判断就会失效。下面是几种更稳妥的处理方式:
方法一:用hasClass()检测类名
$("body").on('click', '.nav', function(e) { if ($(e.target).hasClass('showSite')) { return; // 直接返回,不执行后续代码 } console.log('nav clicked'); // 其他业务代码 })
方法二:用closest()兼容嵌套场景
如果链接内部还有子元素(比如<a class="showSite"><span>Site A</span></a>),e.target会变成内部的<span>,此时hasClass()就会失效。用closest()可以向上查找匹配的元素,解决这个问题:
$("body").on('click', '.nav', function(e) { if ($(e.target).closest('.showSite').length) { return; } console.log('nav clicked'); // 其他业务代码 })
方法三:在链接事件中阻止冒泡
既然你已经有.showSite的专属点击事件,可以直接在那里添加阻止事件冒泡的代码,让事件不会传递到父元素.nav:
$("body").on('click', '.showSite', function(e) { e.stopPropagation(); // 阻止事件向上冒泡到.nav // 你的.showSite事件处理代码 })
这种方式逻辑更清晰,把两个事件的职责分开:链接处理自身逻辑,同时避免触发父元素的事件。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

