【问题标题】::contains for multiple words: 包含多个单词
【发布时间】:2010-05-23 00:54:51
【问题描述】:

我正在使用以下 jQuery

var etag = 'kate'
if (etag.length > 0) {
    $('div').each(function () {
        $(this).find('ul:not(:contains(' + etag + '))').hide();
        $(this).find('ul:contains(' + etag + ')').show();
    });
}​

转向下面的 HTML

<div id="2">
<ul>
  <li>john</li>
  <li>jack</li>
</ul>
<ul>
  <li>kate</li>
  <li>clair</li>
</ul>
<ul>
  <li>hugo</li>
  <li>desmond</li>
</ul>  
<ul>
  <li>said</li>
  <li>jacob</li>
</ul>
  </div>

    <div id="3">
<ul>
  <li>jacob</li>
  <li>me</li>
</ul>
<ul>
  <li>desmond</li>
  <li>george</li>
</ul>
<ul>
  <li>allen</li>
  <li>kate</li>
</ul>  
<ul>
  <li>salkldf</li>
  <li>3kl44</li>
</ul>
</div>

基本上,只要 etag 有一个词,代码就可以完美运行并隐藏那些不包含 etag 的元素。我的问题是,当 etag 是多个单词时(我无法控制它。它来自数据库,并且可能是用空格字符分隔的多个单词的组合)然后代码不起作用..

有什么办法可以做到吗?

【问题讨论】:

    标签: jquery contains


    【解决方案1】:

    此过滤器检查给定字符串中的任何单词是否与元素的文本匹配。

    jQuery.expr[':'].containsAny = function(element, index, match) {
        var words = match[3].split(/\s+/);
        var text = $(element).text();
        var results = $.map(words, function(word) {
            return text === word;
        });
        return $.inArray(true, results) !== -1;
    };
    

    显示和隐藏为:

    $('ul').hide();
    $('li:containsAny(john kate)').parents('ul').show();
    

    查看示例here

    【讨论】:

    • 我认为这不适用于很多情况,例如:jsfiddle.net/ZXdAH
    • 感谢@Nick 指出这一点。更新代码以改用完全匹配,否则“kat”和“joh”之类的词会漏掉。
    • 谢谢。这对我有用,但是,我想澄清一些事情。我正在使用它来过滤基于标签的项目列表。我填充了标签复选框的列表。用户选择 1 个或多个标签并单击过滤器按钮。单击后,代码将遍历选中的复选框并将它们添加到字符串中。然后我运行你的代码来隐藏那些没有标签的,只显示那些有标签的。该列表最多可包含 1000 个项目。这种解决方案可行吗?有没有更好的方法?有性能问题吗?任何现场网站做我需要的?提前致谢!
    • ul 中是否只包含标签? 1000 个项目并不多,但您可能仍会看到 IE 的性能下降。虽然数量很少而且完全可行,但在考虑替代方法之前,您应该编写几个速度测试并在各种浏览器上运行。
    【解决方案2】:

    你可以把它变成一个函数,它接受任意数量的由一个字符分隔的单词,像这样:

    function filter(words) {
        var uls = $('div ul').hide();
        $.each(words.split(' '), function(i, v) {
            uls = uls.filter(':contains(' + v + ')');
        });
        uls.show();
    }
    
    //sample call
    var etag='kate clair'
    filter(etag);
    

    You can see a working demo here

    这会查找包含给定字符串中的所有字词的&lt;ul&gt; 元素。

    【讨论】:

    • 虽然这也有效,但我想我无法正确提问。基本上,您的代码只返回具有
    • kate 和
    • clair 的
        。但它也应该返回
      • allen 和
      • kate。但是,这也是我在项目的另一部分中需要的东西。所以谢谢!一票赞成:)
  • @Emin - 确保在您未来的问题中说明您所追求的是“包含任何”还是“包含所有”(大不同!):) 很高兴你让它工作!
  • 【解决方案3】:

    另一种方法:

    var etag='Some text from server';
    
    if (etag.length > 0) {
        $('div ul').each(function () {
            var el = $(this); // Local reference
            (el.html() === etag) ? el.show() : el.hide(); 
        });
    }​
    

    【讨论】:

      【解决方案4】:

      稍微不同的方法 - 试试这个:

          var etag='kate test blah';
      
          var tags = etag.split(' ');
          $('div ul').each(function () {
            var list = $(this);
            list.hide();
            list.children('li').each(function() {
              var item = $(this);
              if ($.inArray(item.html(), tags) >= 0) list.show();
            });
          });
      

      写在浏览器中,如有错误请见谅!

      -- 编辑--

      实际上,我重新阅读了这个问题,并且该代码不起作用。您需要首先定义行为 - 列表必须包含所有标签,还是只包含要显示的标签之一?

      -- 编辑2--

      代码已更新。有点低效,但它应该可以完成这项工作。

      【讨论】:

      • 感谢您的帮助。该列表可以包含 etag 中的任何单词。
      • 另一个问题:如果它包含任何这些名称,你想隐藏整个 div 吗?还是只是包含该名称的 UL?
      • 我有 > 0,它应该 >= 0。再试一次,告诉我它是否有效。
      猜你喜欢
      相关资源
      最近更新 更多
      热门标签