代码之家  ›  专栏  ›  技术社区  ›  justiceorjustus

JQuery嵌套列表筛选器-当父项匹配时显示所有子项

  •  2
  • justiceorjustus  · 技术社区  · 7 年前

    我有这个jQuery函数,它根据标签文本和文本框输入过滤列表。

    它需要根据匹配类型以两种不同的方式工作:

    1. 如果子项是匹配项,则显示父项。这很有效。
    2. 如果父级匹配,则显示所有子级。这行不通。

    小提琴: https://jsfiddle.net/xtLwnshd/

    var labels = $('label');  // cache this for better performance
    
    $('#filter').keyup(function() {
      var valThis = $(this).val().toLowerCase();
      
      if (valThis == "") {
        labels.parent().show();          // show all lis
      } else {
        labels.each(function() {
          var label = $(this);                    // cache this
          var text = label.text().toLowerCase();
          if (text.indexOf(valThis) > -1) {
            label.parents('li').show()           // show all li parents up the ancestor tree
          } else {
           label.parent().hide();                // hide current li as it doesn't match
          }
        });
      };
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <input type="text" id="filter" />
    <span class="checkbox-list">
    <ul>
        <li>
            <label>Parent1</label>
            <ul>
                <li>
                    <label>Child12</label>
                </li>
                <li>
                    <label>Child3</label>
                </li>
                <li>
                    <label>Item4</label>
                </li>
                <li>
                    <label>Item5</label>
                </li>
            </ul>
        </li>
        <li>
            <label>Item6</label>
        </li>
        <li>
            <label>Item7</label>
            <ul>
                <li>
                    <label>Item4</label>
                </li>
                <li>
                    <label>Item8</label>
                </li>
            </ul>
        </li>
    </ul>
    </span>

    我如何才能让它也适用于#2?我试着在任何一场比赛中给所有的孩子们看,但我认为这是在取消比赛或其他什么。我不太擅长JQuery。

    1 回复  |  直到 7 年前
        1
  •  3
  •   René Schindhelm    5 年前

    我们需要相同的功能,经过数小时的搜索,我决定编写自己的函数。

    其工作原理如下:

    • 第一个循环执行搜索,并根据是否找到匹配项设置每个项目的显示属性。该函数通过将匹配项推入 matches 列表

    • 第二个循环迭代每个匹配项,并检查匹配项的所有子项是否都隐藏,这反过来意味着只有父项是匹配项。

    • 如果所有子项都被隐藏,则父项是匹配项,我们希望让其所有项重新出现。

    它可以突出显示热门歌曲,但那是另一天的事了。

    function filter(inputSelector, dataSelector) {
      let input = document.getElementById(inputSelector);
      let filter = input.value.toUpperCase();
      let ul = document.getElementById(dataSelector);
      let items = ul.getElementsByTagName('li');
    
      // Treffer merken
      let matches = [];
    
      // Suchlauf: Treffer ermitteln, DOM-Elemente zeigen/verstecken
      for (let i = 0; i < items.length; i++) {
        currentItem = items[i];
    
        txtValue = currentItem.textContent || currentItem.innerText || '';
    
        if (txtValue.toUpperCase().indexOf(filter) > -1) {
          currentItem.style.display = '';
          matches.push(currentItem);
        } else {
          currentItem.style.display = 'none';
        }
      }
    
      // Trefferlauf: Alle getroffenen Elemente ablaufen und deren Kinder prüfen
      for (let i = 0; i < matches.length; i++) {
        let childListItemsOfMatch = matches[i].getElementsByTagName('li');
    
        // Ermitteln, ob der Treffer ggf. bei einem Kind lag
        let allChildrenInvisible = true;
        for (let k = 0; k < childListItemsOfMatch.length; k++) {
          if (childListItemsOfMatch[k].style.display == '') {
            allChildrenInvisible = false;
            break;
          }
        }
    
        // Treffer lag beim Parent, also alle Kinder anzeigen
        if (allChildrenInvisible) {
          for (let k = 0; k < childListItemsOfMatch.length; k++) {
            childListItemsOfMatch[k].style.display = '';
          }
        }
      }
    }
    <!DOCTYPE html>
    <html lang="de">
    
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Liste mit Filter</title>
      </head>
    
      <body>
        <h1>Entwurfsmuster</h1>
        <p>Beispielsuchen: 'er', 'gof', 'method', 'lorem'/'ipsum'/'dolar', 'Erzeugungsmuster'</p>
        <input type="text" id="filter" placeholder="Suchbegriff eingeben..." onkeyup="filter('filter', 'data')">
        <ul id="data">
          <li>
            <h2>Erzeugungsmuster</h2>
            <ul>
              <li>Abstract Factory (GoF)</li>
              <li>Builder (GoF)</li>
              <li>Factory Method (GoF)</li>
              <li>Multiton</li>
              <li>Object Pool</li>
              <li>Prototype (GoF)</li>
              <li>Singleton (GoF)</li>
            </ul>
          </li>
          <li>
            <h2>Strukturmuster</h2>
            <ul>
              <li>Adapter (GoF)</li>
              <li>Bridge (GoF)</li>
              <li>Composite (GoF)</li>
              <li>Decorator (GoF)</li>
              <li>Fassade (GoF)</li>
              <li>Flyweight (GoF)</li>
              <li>Proxy (GoF)</li>
            </ul>
          </li>
          <li>
            <h2>Verhaltensmuster</h2>
            <ul>
              <li>Chain of Responsibility (GoF)</li>
              <li>Command (GoF)</li>
              <li>Interceptor</li>
              <li>Interpreter (GoF)</li>
              <li>Iterator (GoF)</li>
              <li>Mediator (GoF)</li>
              <li>Memento (GoF)</li>
              <li>Null Object</li>
              <li>Observer (GoF)</li>
              <li>Protocol Stack</li>
              <li>State (GoF)</li>
              <li>Strategy (GoF)</li>
              <li>Template Method (GoF)</li>
              <li>Visitor (GoF)</li>
            </ul>
          </li>
          <li>
            <h2>Andere Muster</h2>
            <ul>
              <li>Business Delegate</li>
              <li>Data Access Object</li>
              <li>Dependency Injection</li>
              <li>Extension Interface</li>
              <li>Fluent Interface</li>
              <li>Inversion of Control (IoC)</li>
              <li>Model View Controller (MVC)</li>
              <li>Model View Presenter (MVP)</li>
              <li>Model View Update (MVU)</li>
              <li>Model View ViewModel (MVVM)</li>
              <li>Registry</li>
              <li>Repository</li>
              <li>Service Locator</li>
              <li>Threadpool</li>
              <li>Transferobjekt</li>
            </ul>
          </li>
          <li>
            Lorem
            <ul>
              <li>ipsum
                <ul>
                  <li>dolor</li>
                </ul>
              </li>
            </ul>
          </li>
        </ul>
      </body>
    
    </html>