jQuery每个其他元素上的运行函数

时间:2019-04-03 09:44:26

标签: javascript jquery

我正在研究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),这可能会起作用(尚未尝试过),但我认为这将是重复的代码,并且可能会有更好的方法来获得此代码工作。

1 个答案:

答案 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>