我正在研究HTML和jQuery中的一个基本下拉列表元素,并且我试图更好地理解JavaScript和jQuery,因此,这个问题也与代码重构有关。
这就是到目前为止我得到的:
HTML
<li class="nav-item">
<a class="nav-link" href="#">Foo</a>
<div class="subnav">
...
</div>
</li>
JavaScript
const navLink = $('.nav-link');
navLink.each(function () {
let $this = $(this);
$this.click(function (e) {
let hasSubnav = $this.parent().find('.subnav');
if(hasSubnav.length !== 0) {
e.preventDefault();
$this.toggleClass('dropdown-active');
}
hasSubnav.stop(true, true).slideToggle(200);
})
});
此解决方案效果很好。因此,我接下来要做的是检查循环中的另一个元素是否处于活动状态,相应地关闭,然后打开我刚刚单击的元素。
我考虑过将默认的click函数放在这样的每个函数之前:
navLink.click(function () {
$('.subnav').slideUp();
});
navLink.each(function () {
let $this = $(this);
$this.click(function (e) {
let hasSubnav = $this.parent().find('.subnav');
if(hasSubnav.length !== 0) {
e.preventDefault();
$this.toggleClass('dropdown-active');
}
hasSubnav.stop(true, true).slideDown(200);
})
});
但这似乎不起作用。所以我的问题是,即使在每个函数内部,有没有一种漂亮的方法来实现这一目标?我在this帖子中提到了.not(this)
,这可能会起作用(尚未尝试过),但我认为这将是重复的代码,并且可能会有更好的方法来获得此代码工作。
答案 0 :(得分:2)
您的代码现在遍历每个单独的导航链接,并向它们逐个添加点击处理程序。可以删除每个循环,因为您可以一次将单击处理程序添加到所有导航链接。
您所要做的就是在导航链接中添加一个点击处理程序,然后删除活动的类并向上滑动所有打开的下拉菜单,然后再执行逻辑。请参见下面的工作代码示例以供参考:
// Collapse all initially
$(".subnav").slideUp();
// Add click handler to all nav-links
const navLink = $('.nav-link');
navLink.click(function(e) {
// Remove active classes on other elements & slide up
const otherLinks = navLink.not(this);
otherLinks.removeClass('dropdown-active');
otherLinks.parent().find('.subnav').slideUp();
// Slide down the subnav of selected element
let hasSubnav = $(this).parent().find('.subnav');
if (hasSubnav.length !== 0) {
e.preventDefault();
$(this).addClass('dropdown-active');
}
hasSubnav.stop(true, true).slideToggle(200);
})
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<li class="nav-item">
<a class="nav-link" href="#">Foo</a>
<div class="subnav">
<a href="#">Link1</a>
<a href="#">Link2</a>
<a href="#">Link3</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Foo</a>
<div class="subnav">
<a href="#">Link1</a>
<a href="#">Link2</a>
<a href="#">Link3</a>
</div>
</li>