I have table rows like so:
<tr class="parent0 row3" data-parent="0">
<td>...</td>
</tr>
<tr class="parent3 row7" data-parent="3">
<td>...</td>
</tr>
<tr class="parent3 row12" data-parent="3">
<td>...</td>
</tr>
<tr class="parent0 row8" data-parent="0">
<td>...</td>
</tr>
<tr class="parent0 row9" data-parent="0">
<td>...</td>
</tr>
So if I have a click handler:
$(document).on({
"click": function(){
var parentId = $(this).data("parent");
//get previous sibling:
//OPTION A:
var prevParentA =
$(this).prev("parent" + parentId); //works sometimes
//OPTION B:
var prevParentB =
$(this).prevAll("parent" + parentId).eq(0); //works all the time but ugly...
}
}, "tr");
Option A only works when the direct previous item has the same parent, but when that is not the case, prevParentA === []
which is not the desired result.
Option B always seems to work, but it is ugly in that it is selecting ALL of the previous items matching that class and selecting the 1st one it finds.
Is there a better option than Option B?
jQuery does not have something better than your option B. I've long thought this was a missing piece of functionality as I've regularly wanted something like it too. Fortunately, it's not too hard to make your own method:
jQuery.fn.prevFind = function(selector) {
var elems = [];
this.each(function(i, item) {
while (item = item.previousSibling) {
if (item.nodeType == 1) {
if ($(item).is(selector)) {
elems.push(item);
break;
}
}
}
});
return(this.pushStack(elems, "prevFind", selector));
}
The same could be done for a nextFind()
also.
In your example, instead of this:
$(this).prevAll("parent" + parentId).eq(0);
you would use this:
$(this).prevFind("parent" + parentId)
And, here's an implementation of both prevFind()
and nextFind()
that uses some common code:
(function($) {
$.each({
'prevFind' : 'previousSibling',
'nextFind' : 'nextSibling'
}, function(method, dir) {
$.fn[method] = function (selector) {
var elems = [];
this.each(function(i, item) {
while (item = item[dir]) {
if (item.nodeType == 1) {
if ( $.find.matches(selector, [item]).length ) {
elems.push(item);
break;
}
}
}
});
return this.pushStack(elems, method, selector);
};
});
}(jQuery));
Here's the fiddle: http://jsfiddle.net/nDYDL/1/
©2020 All rights reserved.