views:

60

answers:

4

General:

How can I select the first matching ancestor of an element in jQuery?

Example:

Take this HTML block

<table>
    <tbody>
        <tr>
            <td>
                <a href="#" class="remove">Remove</a>
            </td>
        </tr>
        <tr>
            <td>
                <a href="#" class="remove">Remove</a>
            </td>
        </tr>
    </tbody>
</table>

I can remove a row in the table by clicking "Remove" using this jQuery code:

$('.remove').click(function(){
    $(this).parent().parent().hide();
    return false;
});

This works, but it's pretty fragile. If someone puts the <a> into a <div>, for example, it would break. Is there a selector syntax in jQuery that follows this logic:

"Here's an element, now find the closest ancestor that matches some selection criteria and return it"

Thanks

+4  A: 

That would be closest:

$(this).closest('tr').hide();
Kobi
I'll accept this answer when SO lets me. You were too quick.Thanks
Zach
A: 

You can pass a selector to the parent argument I believe.

$('.remove').click(function(){
  $(this).parents("tr:first").hide();
  return false;
});

Or you can use closest as indicated by another answer.

$('.remove').click(function(){
  $(this).closest("tr").hide();
  return false;
});
Gabriel
No, `parent` only looks at the immediate parent and not all ancestors.
interjay
`parent` traverses up a single level of the DOM tree, you would need `parents` instead. Also, the filter expression should be `tr:first` (no space).
karim79
@karim thanks, no coffee yet when I answered. Modified to reflect.
Gabriel
A: 

I prefer using closest as @Kobi points out (+1) as it seems to be the most concise way to do that. Just to point out, you can also use parents:

$(this).parents("tr:first")
karim79
A: 

Assuming you're using jQuery 1.4, you can use .parentsUntil() which will return all of the ancestors upto but NOT including the selected ancestor.

So in your case I would go with something like this:

$('.remove').click(function(){
    $(this).parentsUntil("tr").parent().hide();
    return false;
});
Dave