How to develop a Jquery plugin to find the first child that match with a selector?
Question by Ivan
I’m trying to make a Jquery plugin (findFirst()
) to find the first child with a given characteristics (something in the middle of the find()
and children()
functions. For instance, given this markup:
<div id="start">
<div>
<span>Hello world</span>
<ul class="valid-result"> ... </ul>
<ul class="valid-result">
<li>
<ul class="not-a-result"> ... </ul>
</li>
</ul>
<div>
<ul class="valid-result"> ... </ul>
</div>
</div>
</div>
If you ask for $("#start").findFirst('ul')
it should return all ul lists that I have tagged with the valid-result class, but not the ul with class not-a-result. It is, this function has to find the first elements that matches with a given selector, but not the inner elements that match this selector.
This is the first time I try to code a Jquery function, and what I’ve already read doesn’t helps me too much with this. The function I have developed is this:
jQuery.fn.findFirst = function (sel) {
return this.map(function() {
return $(this).children().map(function() {
if ($(this).is(sel)) {
return $(this);
} else {
return $(this).findFirst(sel);
}
});
});
}
It works in the sense it tries to return the expected result, but the format it returns the result is very rare for me. I suppose the problem is something I don’t understand about Jquery. Here you have the JFiddle where I’m testing.
EDIT
The expected result after $("#start").findFirst('ul')
is a set with all UL that have the class ‘valid-result’ BUT it’s not possible to use this class because it doesn’t exist in a real case (it’s just to try to explain the result).
This is not equivalent to first(), because first returns only one element!
Answer by charlietfl
You could do something like this:
var selector='ul';
var $results= $('#start '+selector).not( selector +' '+selector);
The not()
method will exclude elements that match selector but are also descendents of the same selector
Answer by Starx
You don’t need to build a plugin. use jQuery inbuilt .first()
and as suggested by Mark, you can also use first selector :first
$("#yourselector ul").first();
Here is the usages in your case
$("#start").find("ul").first().css("background", "red");
//For Short $("#start ul").first()
To use class filter, use the attribute selector
$("#start").find("ul[class=valid-result]").first().css("background", "red");
//For Short $("#start ul[class=valid-result]").first()
Update
If you want to highlight only the outer ul’s with class valid-result
then first()
is not needed at all
$("#start ul[class=valid-result]").css("background", "red");
But, since the inner ul will also share the background on my example, you might have to set different background for inner ul
‘s. Here is an example
Update 2
If you want to select the first level of the <ul>
then
$("#start div").chilrent("ul"); //this will return the first level of ul inside the div