问题
I am using the following jQuery
var etag = 'kate'
if (etag.length > 0) {
$('div').each(function () {
$(this).find('ul:not(:contains(' + etag + '))').hide();
$(this).find('ul:contains(' + etag + ')').show();
});
}
towards the following 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>
basically, as long as etag has one word, the code works perfectly and hides those elements who do not contain etag. My problem is, when etag is multiple words (and I don't have control over it. Its coming from a database and could be combination of multiple words separated with space char) then the code does not work..
is there any way to achieve this?
回答1:
This filter checks if any of the words in the given string match the text of the element.
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;
};
Show and hide as:
$('ul').hide();
$('li:containsAny(john kate)').parents('ul').show();
See an example here.
回答2:
You could turn this into a function that takes any number of words separated by a character, like this:
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
This finds <ul>
elements that contain all the words in the given string.
回答3:
Another approach:
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:
A slightly different approach - try this:
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();
});
});
Written in the browser, so sorry if there are any bugs!
-- edit --
Actually, I reread the question, and that code won't work. You need to define the behaviour more first - does the list have to contain all of the tags, or just one of the tags to be shown?
-- edit 2 --
Code updated. Kind of inefficient, but it should do the job.
来源:https://stackoverflow.com/questions/2890334/contains-for-multiple-words