jQuery :contains()选择器大小写问题

66

我的HTML代码看起来像这样

<input id="txt" value=""></input>

<div class="link-item">jK</div>
<div class="link-item">JFOO</div>

我的 JS

$('#txt').keyup(function(){

    var txtsearch = $('#txt').val();
    var filt = $("div.link-item:contains('" + txtsearch +"')");

    $("div.link-item").css("display", "none")
        .filter(filt)
        .css("display", "block");

});

我希望能够在客户端动态过滤内容。当我键入大写字母J时,它只返回第二个div,但我希望获取包含j的所有div,无论是大小写。


这不是问题(如果你的意思是它返回第一个div),供您参考,您可以像这样编写输入:<input id="txt" value="" />。 - noob
4
可能是重复问题:https://dev59.com/7XVC5IYBdhLWcg3wxEN1 和 https://dev59.com/wHI95IYBdhLWcg3wsQFm - qiao
可能是 https://dev59.com/wHI95IYBdhLWcg3wsQFm 的重复问题。 - T I
4个回答

163
您可以将.contains筛选器更改为不区分大小写,或者创建自己的选择器。
jQuery.expr[':'].icontains = function(a, i, m) {
  return jQuery(a).text().toUpperCase()
      .indexOf(m[3].toUpperCase()) >= 0;
};

这将创建一个新的选择器:icontains(或您可以将其命名为不区分大小写的包含,或者任何适合您的名称)。 它的用法与contains相同: $('div:icontains("Stack")'); 将匹配:

<div>stack</div>
<div>Stack</div>
<div>StAcKOverflow</div>

或者覆盖现有的.contains过滤器:

jQuery.expr[':'].contains = function(a, i, m) {
  return jQuery(a).text().toUpperCase()
      .indexOf(m[3].toUpperCase()) >= 0;
};

有了这个,

$("div:contains('John')");

将选择这三个元素:

<div>john</div>
<div>John</div>
<div>hey hey JOHN hey hey</div>

4
我认为你应该创建一个单独的选择器,而不是覆盖默认选择器。 - Stefan
老帖子了,但是这太棒了。谢谢,伙计。真希望我一个月前就发现了它。 - Will
8
如果有人和我一样不明白function(a,i,m)中的a,i,m指代什么,可以参考这个链接 http://jquery-howto.blogspot.in/2009/06/jquery-custom-selectors-with-parameters.html。 - Abdul Hameed
2
谢谢你的链接,@AbdulHameed!现在我明白了为什么m[3]。 - Chris Walker
哇 - 这个很好用!非常有用。谢谢! - Dave
显示剩余5条评论

25

为什么不使用filter函数,并传入一个使用不区分大小写的正则表达式的函数?

var filteredDivs = $("div.link-item").filter(function() {
    var reg = new RegExp(txtsearch, "i");
    return reg.test($(this).text());
});

演示


对我来说,与:contains或者 :icontains相比,这不容易记住。 - OG Sean
@OGSean 但是你需要记住如何创建 :icontains 选择器。 - Lukas
1
@Lukas 是的,没错,我想我更喜欢jQuery中现有的选择器模式。 - OG Sean

11

以下是我的贡献,希望能有所帮助 :)

$('#txt').keyup(function() {
    var query = $(this).val();
    $("div.link-item")
        .hide()
        .filter(':contains("' + query + '")')
        .show();
});

:contains() 选择器 区分大小写。

匹配的文本可以直接出现在选定元素内部、元素的任何后代内或两者组合中。与属性值选择器一样,:contains() 括号内的文本可以作为裸字写入或用引号括起来。但被选中的文本必须与查询时大小写一致

此外,我创建了一个演示,供有兴趣的人尝试使用。

更新

抱歉,可能误读了你的问题。

http://bugs.jquery.com/ticket/278 找到了这个 jQuery 表达式,可创建一个新的不区分大小写的选择器,并更新了我的演示

$.extend($.expr[':'], {
  'containsi': function(elem, i, match, array) {
    return (elem.textContent || elem.innerText || '').toLowerCase()
        .indexOf((match[3] || "").toLowerCase()) >= 0;
  }
});

1

我不相信有一种使用原始选择器的方法来实现这个。 contains 选择器是区分大小写的,似乎没有不区分大小写的版本。我认为最好的方法是使用一个过滤器手动查询对象。

var filt = function (unused) {
  $(this).text().toLowerCase().indexOf(txtSearch.toLowerCase()) !== -1;
};

1
如果你只想使用开箱即用的核心功能...否则,使用另一个不区分大小写的选择器扩展jQuery似乎非常不错! - OG Sean

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接