jQuery过滤列表而不隐藏父母

时间:2018-08-28 19:06:53

标签: jquery search filtering

我有一个这样的列表:

<ul>
  <li class="folder">Foder A</li>
  <ul>
    <li>Item 1A</li>
    <li>Item 2A</li>
    <li>Item 3A</li>     
  </ul>
  <li class="folder">Foder B</li>
  <ul>
    <li class="folder">Sub-Foder C</li>
    <ul>
      <li>Item 1C</li>
    </ul>
    <li>Item 1B</li>
    <li>Item 2B</li>
    <li>Item 3B</li>     
  </ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>

这个“搜索”脚本:

$(document).ready(function() {
$("input[type='search']").keyup(function() {
  var filter = $(this).val();
  $("ul li").each(function() {
    if ($(this).text().search(new RegExp(filter, "i")) < 0) {
      $(this).hide();
      }
    else {
      $(this).show();
      }
    });
  });
});

但是它正在过滤所有<li>s,并且当然甚至隐藏了“文件夹”。

如何继续显示包含搜索结果的父母<li class="folder">

1 个答案:

答案 0 :(得分:0)

我稍微修改了您的初始代码,我想我现在已经有了所需的用例。但是首先让我们简要地看看我所做的更改。

  1. 我没有遍历每个li上的所有keyup元素,而是使用$('ul li').toArray()在文档准备就绪时获取NodeElements数组。
  2. 最初,我们隐藏了keyup上的所有内容
  3. 如您所见,我使用了一些不同的方法来过滤出匹配的值。由于我的列表现在是一个数组,因此我正在使用filterMDN)函数,该函数将返回一个新的基于NodeElement的数组,这些NodeElements符合条件entry.innerText.includes(value)({{3} })。
  4. 然后,我遍历结果数组并将show()应用于每个条目,并且我还使用了parentsUntil('.top-level')(我将类top-level添加到了最顶部的{{1} }元素)来获取我当前条目的祖先(与搜索匹配的祖先),并且我使用<ul>MDN - String.includes)来定位那些祖先的前一个li元素。最后,我在这些元素上应用了prev(...)

show(...)的确切定义如下:

  

获取当前匹配元素集中每个元素的祖先,直到但不包括选择器,DOM节点或jQuery对象匹配的元素。

     

jQuery docs

SNIPPET

parentsUntil(...)
$(document).ready(function() {
  var list = $('ul li').toArray();

  $("input[type='search']").keyup(function() {
    $('ul li').hide();
    var value = $(this).val();

    var result = list.filter(function(entry) {
      return entry.innerText.includes(value);
    });

    result.forEach(function(entry) {
      $(entry).show().parentsUntil('.top-level').prev('li').show();
    });
  });
});