【问题标题】:Filter elements by search values - multiple words按搜索值过滤元素 - 多个词
【发布时间】:2023-04-07 11:54:01
【问题描述】:

我有一个由 DIV 和一个 INPUT 搜索框组成的列表:

<input id="search" type="text">

<div>Caramel Apples</div>
<div>Strawberry Lemonade</div>
<div>Pineapple Cake</div>
<div>Apple Pie</div>
<div>Cherry Ice Cream</div>

在搜索框中输入时,我想进行实时更新以仅显示与所有搜索关键字匹配的行,即使它们是部分关键字。如果我输入“app ca”,我应该会得到“Caramel Apples”和“Pineapple Cake”。

我无法让标准的 jQuery Attribute Contains Selector [name*="value"] 为多个“价值”工作。 Multiple Attribute Selector 似乎也不起作用,可能是因为我只对一个属性进行操作,而不是多个。

另外,我还需要它不区分大小写。

我发现了一个类似的问题HERE,但它只对关键字进行 OR 过滤,而不是 AND。它也不是动态的,例如正在输入关键字。这可能是一个好的开始,但我不知道如何修改它以适用于我的情况。

【问题讨论】:

    标签: jquery filter


    【解决方案1】:

    按多个搜索词过滤项目

    对于多个单词,您必须按空格分隔并将每个部分视为有效的搜索查询:

    const EL_input = document.querySelector("#search");
    const ELS_items = document.querySelectorAll("div");
    
    const filterItems = (text) => {
      const words = text.trim().toLowerCase().replace(/ +/g, " ").split(" ");
      console.log(words);
      ELS_items.forEach(EL => {
        const cont = EL.textContent.trim().toLowerCase();
        const hasWord = words.some((w) => cont.includes(w));
        EL.classList.toggle("u-none", !hasWord);
      });
    }
    
    EL_input.addEventListener("input", () => {
      filterItems(EL_input.value);
    });
    /* Utility classes */
    
    .u-none {
      display: none;
    }
    <input id=search type=text autocomplete=off>
    
    <div>Caramel Apples</div>
    <div>Strawberry Lemonade</div>
    <div>Pineapple Cake</div>
    <div>Apple Pie</div>
    <div>Cherry Ice Cream</div>

    按单个搜索词过滤项目

    const EL_input = document.querySelector("#search");
    const ELS_items = document.querySelectorAll("div");
    // BE MORE SPECIFIC WITH YOUR SELECTORS! Use a class instead of "div"
    
    const filterItems = (text) => {
      text = text.trim().toLowerCase();
      ELS_items.forEach(EL => {
        const cont = EL.textContent.trim().toLowerCase();
        const hasText = cont.includes(text);
        EL.classList.toggle("u-none", !hasText);
      });
    }
    
    EL_input.addEventListener("input", () => {
      filterItems(EL_input.value);
    });
    /* Utility classes */
    
    .u-none {
      display: none;
    }
    <input id="search" type="text" autocomplete=off>
    
    <div>Caramel Apples</div>
    <div>Strawberry Lemonade</div>
    <div>Pineapple Cake</div>
    <div>Apple Pie</div>
    <div>Cherry Ice Cream</div>

    使用 jQuery 非常相似,唯一的区别是不必要地加载了 relatively big 库(在此日期(2021 年)),但代码完全相同:

    jQuery - 通过多个搜索词过滤项目

    const $input = $("#search");
    const $items = $("div");
    // BE MORE SPECIFIC WITH YOUR SELECTORS! Use a class instead of "div"
    
    function filterItems(text) {
      const words = text.trim().toLowerCase().replace(/ +/g, " ").split(" ");
      $items.each(function() {
        const cont = $.trim($(this).text().toLowerCase());
        const hasText = words.some((w) => cont.includes(w));
        $(this).toggleClass("u-none", !hasText);
      });
    }
    
    $input.on("input", function() {
      filterItems($(this).val());
    });
    /* Utility classes */
    
    .u-none {
      display: none;
    }
    <input id="search" type="text" autocomplete=off>
    
    <div>Caramel Apples</div>
    <div>Strawberry Lemonade</div>
    <div>Pineapple Cake</div>
    <div>Apple Pie</div>
    <div>Cherry Ice Cream</div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

    jQuery - 按单个搜索词过滤项目

    const $input = $("#search");
    const $items = $("div");
    // BE MORE SPECIFIC WITH YOUR SELECTORS! Use a class instead of "div"
    
    function filterItems(text) {
      text = text.trim().toLowerCase();
      $items.each(function() {
        const cont = $.trim($(this).text().toLowerCase());
        const hasText = cont.includes(text);
        $(this).toggleClass("u-none", !hasText);
      });
    }
    
    $input.on("input", function() {
      filterItems($(this).val());
    });
    /* Utility classes */
    
    .u-none {
      display: none;
    }
    <input id="search" type="text" autocomplete=off>
    
    <div>Caramel Apples</div>
    <div>Strawberry Lemonade</div>
    <div>Pineapple Cake</div>
    <div>Apple Pie</div>
    <div>Cherry Ice Cream</div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

    【讨论】:

    • 感谢您的建议。我主要对 jQuery 解决方案感兴趣,所以我尝试了您的“jQuery - 通过多个搜索词过滤项目”sn-p。不幸的是,它并不能完全按照我在原始问题中的要求工作。它仍然是 OR 逻辑而不是 AND。如果我输入“app ch”,我会得到所有的“apples”和“cherry”。我不应该得到任何结果,因为“app”和“ch”没有一起出现在其中。
    • @jfriend 使用 .every 而不是 .some
    【解决方案2】:

    您可以使用此代码:

    <input id="search" type="text">
    
    <div>Caramel Apples</div>
    <div>Strawberry Lemonade</div>
    <div>Pineapple Cake</div>
    <div>Apple Pie</div>
    <div>Cherry Ice Cream</div>
    
    
    $(document).ready(function(){
        $("#search").on("keyup", function() {
            var value = $(this).val().toLowerCase();
            $("div").css("display", function() {
                return this.innerText.toLowerCase().indexOf(value) > -1 ? "":"none"
            });
        });
    });
    

    【讨论】:

    • 这不能按预期工作。对所有“apple”项目键入“app”过滤器,但只需点击空格会立即删除所有结果。
    猜你喜欢
    • 2012-11-02
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 2018-10-25
    相关资源
    最近更新 更多