【问题标题】:removeClass from all other elements except the target parent除目标父元素外的所有其他元素中的 removeClass
【发布时间】:2015-12-23 21:19:12
【问题描述】:

我正在尝试从一个简单的嵌套列表构建一个简单的下拉菜单。

我想做两件事:

  • 当一个链接被点击时,toggleClass 它的父 li 带有 '.open'
  • 当用户点击上述以外的任何地方时,从所有 li 中删除 '.open' 类

HTML 应该如下所示:

<ul>
   <li class="parent-item">
      <a href="#">Link</a>
      <ul>
         <li><a href="#">Child</a></li>
         <li><a href="#">Child</a></li>
         <li><a href="#">Child</a></li>
      </ul>
   </li>
   <li><a href="#">Link</a></li>
   <li class="parent-item">
      <a href="#">Link</a>
      <ul>
         <li><a href="#">Child</a></li>
         <li><a href="#">Child</a></li>
         <li><a href="#">Child</a></li>
      </ul>
   </li>
</ul>

jQuery 看起来像这样:

$('html').click(function(e) {
      $('.parent-item').removeClass('open');    
      if($(e.target).parent().hasClass('parent-item')) {
         e.preventDefault();
         $(e.target).parent().toggleClass('open');
      }     
});

removeClass 线干扰了 toggleClass 线,阻止了 toggleClass 在第二次点击时触发。

Here is a fiddle

任何想法我做错了什么?

【问题讨论】:

  • 谢谢。我完全了解它是如何工作的。

标签: jquery


【解决方案1】:

我相信它可以更简单一些,因为您只想在点击位于.parent-item 内时执行任何操作:

// The second argument means we only get called if the click
// travels through a .parent-item en route to the HTML element
$('html').on("click", ".parent-item", function(e) {
  // Don't follow the link
  e.preventDefault();

  // Toggle 'open' on this .parent-item
  $(this).toggleClass('open');

  // Remove it from any *other* .parent-item that has it
  $('.parent-item.open').not(this).removeClass('open');
  // Ignores this one --^^^^^^^^^^
});

实例:

// The second argument means we only get called if the click
// travels through a .parent-item en route to the HTML element
$('html').on("click", ".parent-item", function(e) {
  // Don't follow the link
  e.preventDefault();

  // Toggle 'open' on this .parent-item
  $(this).toggleClass('open');

  // Remove it from any *other* .parent-item that has it
  $('.parent-item.open').not(this).removeClass('open');
});
.open {
  background-color: yellow;
}
<ul>
   <li class="parent-item">
      <a href="#">Link</a>
      <ul>
         <li><a href="#">Child</a></li>
         <li><a href="#">Child</a></li>
         <li><a href="#">Child</a></li>
      </ul>
   </li>
   <li><a href="#">Link</a></li>
   <li class="parent-item">
      <a href="#">Link</a>
      <ul>
         <li><a href="#">Child</a></li>
         <li><a href="#">Child</a></li>
         <li><a href="#">Child</a></li>
      </ul>
   </li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

您在 cmets 中说过,您希望在任何.parent-item 之外单击 以关闭任何打开的。为此,我们稍作调整,返回未过滤的 html 点击处理程序:

// The second argument means we only get called if the click
// travels through a .parent-item en route to the HTML element
$('html').on("click", function(e) {
  // If this click came through a parent item, get it
  var parentItem = $(e.target).closest(".parent-item");

  // Remove 'open' from any *other* .parent-item that has it
  $('.parent-item.open').not(parentItem).removeClass('open');

  // Was this click on a .parent-item?
  if (parentItem.length) {
    // Don't follow the link
    e.preventDefault();

    // Toggle 'open' on this .parent-item
    parentItem.toggleClass('open');
  }
});

实例:

// The second argument means we only get called if the click
// travels through a .parent-item en route to the HTML element
$('html').on("click", function(e) {
  // If this click came through a parent item, get it
  var parentItem = $(e.target).closest(".parent-item");
  
  // Remove 'open' from any *other* .parent-item that has it
  $('.parent-item.open').not(parentItem).removeClass('open');
  
  // Was this click on a .parent-item?
  if (parentItem.length) {
    // Don't follow the link
    e.preventDefault();

    // Toggle 'open' on this .parent-item
    parentItem.toggleClass('open');
  }
});
.open {
  background-color: yellow;
}
<ul>
   <li class="parent-item">
      <a href="#">Link</a>
      <ul>
         <li><a href="#">Child</a></li>
         <li><a href="#">Child</a></li>
         <li><a href="#">Child</a></li>
      </ul>
   </li>
   <li><a href="#">Link</a></li>
   <li class="parent-item">
      <a href="#">Link</a>
      <ul>
         <li><a href="#">Child</a></li>
         <li><a href="#">Child</a></li>
         <li><a href="#">Child</a></li>
      </ul>
   </li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

【讨论】:

  • 这真的很棒,并且大大简化了它。谢谢!
  • 我只是注意到,当用户单击其他任何位置(即当前 .open > a 以外的任何位置)时,它不会从所有元素中删除 .open 类。我想知道它是如何工作的?
  • @user1444027:完成。它看起来像很多代码,但这只是因为 cmets。实际上是8行。 :-)
【解决方案2】:

您可以将移除类移到底部并排除当前项目

$('html').click(function(e) {
  var $curr;
  if ($(e.target).parent().hasClass('parent-item')) {
    e.preventDefault();
    $curr = $(e.target).parent().toggleClass('open');
  }
  $('.parent-item.open').not($curr).removeClass('open');
});
.parent-item > ul {
  display: none;
}
.parent-item.open > ul {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li class="parent-item">
    <a href="#">Link</a>
    <ul>
      <li><a href="#">Child</a>
      </li>
      <li><a href="#">Child</a>
      </li>
      <li><a href="#">Child</a>
      </li>
    </ul>
  </li>
  <li><a href="#">Link</a>
  </li>
  <li class="parent-item">
    <a href="#">Link</a>
    <ul>
      <li><a href="#">Child</a>
      </li>
      <li><a href="#">Child</a>
      </li>
      <li><a href="#">Child</a>
      </li>
    </ul>
  </li>
</ul>

【讨论】:

    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    • 2015-05-13
    • 2012-05-20
    • 2016-03-28
    • 2019-06-25
    相关资源
    最近更新 更多