【问题标题】:How do I hide a parent li-element whose child ul-li elements are all hidden using jQuery?如何使用 jQuery 隐藏其子 ul-li 元素全部隐藏的父 li 元素?
【发布时间】:2011-07-15 01:55:48
【问题描述】:

我有一组嵌套的 ul,如下所示:

<ul id="educationList">
    <li class="category"><p>Media production</p>
       <ul>
          <li class="education" style="display: block;">
             <a href="#">Real time 3D animation</a>
          </li>
          <li class="education" style="display: block;">
             <a href="#">Filming with Steadicam</a>
          </li>
          <li class="education" style="display: block;">
             <a href="#">Sound Effects</a>
          </li>
       </ul>
    </li>
</ul>

顶部的 ul (educationList) 包含一个类别列表,每个类别都有一个子列表 (ul),其中包含在该类别下排序的教育。经典的嵌套列表结构。在上面的示例代码中,我只有一个类别——在实际代码中,有很多类别。

我有一个 jQuery 过滤功能,可以显示/隐藏具有“教育”类的 li 元素(子列表元素)。有时这个过滤函数会隐藏所有子列表元素,所以 HTML 看起来像这样:

<ul id="educationList">
    <li class="category"><p>Media production</p>
       <ul>
          <li class="education" style="display: none;">
             <a href="#">Real time 3D animation</a>
          </li>
          <li class="education" style="display: none;">
             <a href="#">Filming with Steadicam</a>
          </li>
          <li class="education" style="display: none;">
             <a href="#">Sound Effects</a>
          </li>
       </ul>
    </li>
</ul>

不同之处在于所有子列表元素现在都具有内联样式display: none。突然之间,我对“类别”类的父母 li 没有真正的用处,因为该类别下没有教育。

现在我正在寻找一种智能方法来查找没有可见儿童教育列表项的所有类别列表项,并简单地隐藏类别列表项。每次进行任何过滤时,我都必须运行此功能,因为过滤会影响儿童教育列表项——一些可见的将被隐藏,而一些隐藏的将再次可见。

另外 - 我会有很多元素,所以如果代码不是太耗费资源,这是一个优势。不过,现在不是挑剔的时候。任何解决方案都可以,我将不得不稍后进行优化。

提前致谢! /托马斯·卡恩

【问题讨论】:

    标签: jquery nested hide element show


    【解决方案1】:

    这应该很简单:

    $('li.category:not(:has(li:visible))').hide();
    

    现场示例:http://jsfiddle.net/wTKEQ/

    如果按原样运行,则该类别将被隐藏。如果您将一个或多个子项更改为display:block,则不会发生任何事情。

    【讨论】:

    • 这也是你能做到的最耗费资源的方式:P
    • 还是很酷的,我不认为会有一千个。
    • @Eugene:如果您阅读了这个问题,它清楚地表明会有很多元素,并且性能考虑是一个优势。当一个 OP 清楚地说明这一点时,在我看来,给他尽可能慢的答案并不是很酷,无论单线如何震撼你的世界。
    • @Martin - 很好地发现了性能。但是请尝试用一些证据来支持它:P jsperf.com/menu-elements
    • @Martin - 为了 {diety} 清淡点。这是一个玩笑的尝试,并证明你是正确的。你不需要去喷你的明显优越凭证:rolleyes:
    【解决方案2】:

    这是不完全忽略资源使用的简单方便的jQuery解决方案:

    $('li.category').each(function() {
      var $li = $(this);
      if(!$li.find('li:visible').length) {
        $li.hide();
      }
    });
    

    如果你需要性能优化,你可以这样做,它没有.each的开销:

    var categories = $('li.category');
    for(var i=0,category;category = categories.eq(i);i++) {
      if(!category.find('li:visible').length) {
        category.hide();
      }
    }
    

    编辑:修复优化版本中的错误

    【讨论】:

    • 您的两个示例中的第一个非常完美!我必须添加一个 $("li.category").show();在它之前我每次运行该功能时都会想到,因为隐藏父母会自动隐藏所有孩子,但在那之后它就像一个魅力。在第二个示例中,我必须在 if 子句和 hide 命令之前用 $(category) 替换 category,但之后效果很好!
    • 您的第二个示例失败, .find 不是类别的函数。您需要$(category) 代替每个category
    • @jamiec:你是对的,也是错的。由于我从 jQuery 集合中提取元素的方式,我的示例不起作用。然而,正确的做法是不要重新包装元素,而是使用 categories.eq(i) 而不是 categories[i] 提取包装后的版本
    【解决方案3】:
    $("li.category").each(function(){
       if($(this).find("li:visible").size() == 0)$(this).hide();
    });
    

    【讨论】:

      【解决方案4】:
      $("li.category").each(function(){
      if($(this).find("li.education").css("display")=="none")
      {
      $(this).hide();
      }
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-11-24
        • 2011-09-17
        • 2014-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多