jQuery使用关键字搜索和过滤

时间:2017-09-16 01:21:35

标签: javascript jquery web

我试图编写一个搜索/过滤功能,根据用户键入的内容搜索带有data- *属性的无序列表项。

<input type="text" placeholder="Search..." id="myInput" onkeyup="myFunction()">        
<ul id="myUL">
    <li><a href="#" data-keywords="photography">Digital Media Design</a></li>
    <li><a href="#" data-keywords="computers">Information Technology</a></li>
    <li><a href="#" data-keywords="coding">Programming</a></li>
</ul>

这是我到目前为止的代码,它仅适用于一个数据关键字项。我需要帮助才能根据多个关键字调出搜索结果。

<li><a href="#" data-keywords="photography photoshop illustrator premiere">Digital Media Design</a></li>

// Search functionality
function myFunction() {
    // Declare variables
    var input, filter, ul, li, a, i;
    input = document.getElementById('myInput');
    filter = input.value.toUpperCase();
    ul = document.getElementById("myUL");
    li = ul.getElementsByTagName('li');
    // Loop through all list items, and hide those who don't match the search query
    for (i = 0; i < li.length; i++) {
        a = li[i].getElementsByTagName("a")[0];
        if (a.innerHTML.toUpperCase().indexOf(filter) > -1 || $(a).data("keywords") === filter.toLocaleLowerCase()) {
            li[i].style.display = "";
        } else {
            li[i].style.display = "none";
        }
    }
}

如果有人建议我如何改进那些令人敬畏的代码!

2 个答案:

答案 0 :(得分:0)

这对我有用:

// Get all li's and create an array with each li's data attributes
const lis = document.querySelector("#myUL").children;

const keywordArray = [];

[...lis].forEach((li, i) => {
  keywordArray.push(li.children[0].dataset.keywords);
});

function myFunction() {
  //Show any previous hidden li's
  [...lis].forEach(li => {
    li.style.display = 'block';
  });

  const inputArray = document.querySelector('#myInput').value.split(' ');
  const indexes = [];
  // For each word in the input field, search through our data attribute array
  inputArray.forEach(term => {
    keywordArray.forEach((keywords, i) => {
      keywords.split(' ').forEach(keyword => {
        // If we find a match, add the index of the data attribute array, which
        // will be the same as the index of the li element
        if (keyword === term) {
          indexes.push(i);
        }
      });
    });
  });
  // If we have a match, hide every non-matching li'
  if (indexes.length) {
    [...lis].forEach((li, i) => {
      if (!indexes.includes(i)) {
        li.style.display = 'none';
      }
    });
  }
}

为了澄清,您是否希望使用其他搜索字词来使搜索更具体或更不具体?因为我的解决方案使搜索不那么具体,因为它会显示任何匹配任何搜索词的li。

答案 1 :(得分:0)

我做了一些假设:

  • 如果提供了多个搜索字词,则必须全部匹配。
  • 搜索字词必须是字母,a-z。这可以很容易地改为包括其他字符,例如数字,但最终我们需要一些方法来决定一个术语的结束和下一个术语的开始。
  • 匹配基于子字符串。

最需要解释的是那个正则表达式。它使用标准技巧进行and匹配:

Regular Expressions: Is there an AND operator?

因此,如果您搜索digital photography,RegExp将等同于:

/(?=.*digital)(?=.*photography)/i

如果您希望搜索or而不是and,则只需相应地调整RegExp即可。如果你想做一个start-with匹配而不是substring,你可以在每个搜索词之前输入\b(在字符串中适当地转义为\\b)。

我希望其余的都是不言自明的,我试着接近问题中的代码。

&#13;
&#13;
// Search functionality
function myFunction() {
    // Declare variables
    var input = document.getElementById('myInput'),
        filter = input.value,
        ul = document.getElementById('myUL'),
        lis = ul.getElementsByTagName('li'),
        searchTerms = filter.match(/[a-z]+/gi),
        re, index, li, a;
        
    if (searchTerms) {
        searchTerms = searchTerms.map(function(term) {
            return '(?=.*' + term + ')';
        });
        
        re = new RegExp(searchTerms.join(''), 'i');
    } else {
        re = /./;
    }

    // Loop through all list items, and hide those who don't match the search query
    for (index = 0; index < lis.length; index++) {
        li = lis[index];
        a = li.firstChild;

        if (re.test(a.innerHTML + ' ' + a.getAttribute('data-keywords'))) {
            li.style.display = '';
        } else {
            li.style.display = 'none';
        }
    }
}
&#13;
<input type="text" placeholder="Search..." id="myInput" onkeyup="myFunction()">

<ul id="myUL">
  <li><a href="#" data-keywords="photography photoshop illustrator premiere">Digital Media Design</a></li>
  <li><a href="#" data-keywords="computers">Information Technology</a></li>
  <li><a href="#" data-keywords="coding">Programming</a></li>
</ul>
&#13;
&#13;
&#13;