考虑这个简单的 html 列表:
<ul>
<li><a href="http://google.com/">Test</a></li>
<li><a href="http://google.com/">Test2</a>
<ul>
<li><a href="http://google.com">Test2 - 1</a></li>
<li><a href="#3">Test2 - 2</a></li>
</ul>
</li>
</ul>
现在这3条 jQuery 行让它可以折叠:
$('ul > li').on('click', function(e) {
e.preventDefault();
$(this).find('ul').slideToggle();
});
这里的问题是,如果在更深层ul
中点击链接,我希望它遵循链接,jQuery中的链接将是:
if(this.nodeName != 'A') {
e.preventDefault();
}
目前nodeName
为LI
且不是最后点击的子元素。
问题:是否可以在没有第二个事件处理程序的情况下执行此操作 ? (即:$('ul > li ul li a').click()
)
我尝试了e.stopPropagation
和许多其他css selectors
(ul > *
,ul li
等等,但没有成功。
答案 0 :(得分:1)
试试这个:
$('li > ul').prev().on('click', function(e) {
e.preventDefault();
$(this).next().slideToggle();
});
here指向jsfiddle的链接。li > ul
选择器找到ul
的每个li
子项,然后.prev()
选择previosu兄弟(即a
代码)。这样我们就可以阻止a
标签的默认行为(即跟随链接)和下一步滑动切换(即ul
)
答案 1 :(得分:0)
经过一些研究,我得出了这个答案:
$('ul > li').on('click', function(e) {
e.stopPropagation();
if(!$(this).find('ul').length == 0) {
e.preventDefault();
$(this).find('ul').slideToggle();
}
});
因此,如果在单击的元素中没有建立ul
元素,它将跟随链接。如果您有更好的解决方案,请分享:)。
此解决方案不适用于ul
的指定ID
:
$('ul#test > li').on('click', function(e) {
e.stopPropagation();
if(!$(this).find('ul').length == 0) {
e.preventDefault();
$(this).find('ul').slideToggle();
}
});
请参阅updated fiddle here,有人可以解释原因吗?
好的,感谢Simon
我已经通过li
ul#test
的听众纠正了我:
$('ul#test').on('click', 'li', function(e) {
e.stopPropagation();
if(!$(this).find('ul').length == 0) {
e.preventDefault();
$(this).find('ul').slideToggle();
}
});
很棒!
答案 2 :(得分:0)
由于你的根选择器是'ul > li'
,它只会与LI匹配。即,您无法将点击匹配到使用该选择器绑定的处理程序内的其他元素。
你可以做的是在处理程序中使用更通用的选择器和过滤器:
例如:
$('ul *').on('click', function(e) {
// leaf LIs only
if($(this).is('li') && $(this).children().length == 0) {
e.preventDefault();
$(this).find('ul').slideToggle();
}
});
OR,您可以组合选择器并使用 one 处理程序处理它,如:
$('ul > li, ul > li ul li a').on('click', function(e) {
if($(this).is('a')) return true; // follow links
e.stopPropagation();
$(this).find('ul').slideToggle();
}