views:

184

answers:

5

Say I have the following markup:

<div>
    <h3><a href="">link I want to select</a></h3>
        <div>
             <h3><a href="">link</a></h3>
        </div>
    <h3><a href="">link I want to select</a></h3>
    <h3><a href="">link I want to select</a></h3>
    <a href="">link</a>
</div>

Assuming the following...

  • The elements I want to find are all at the same level of nesting
  • I may not know what the specific nesting elements are (so can't use a specific selector)

...is there a clever way to select 'first anchor tag, and all other anchor tags that are nested at that same level' so that it returns the 1st, 3rd, and 4th links?

Worse case, we need to go in and just add specific classes to our HTML, but it'd be great if this could be done via pure selectors.

A: 

If you want to select all links under an h3:

var $links = $('h3 a');

Edit: Sorry, I didn't read that closely apparently. Maybe you could try the following (note this is not tested):

var $links = $(div > * > a);
Keith Rousseau
right, but that's now what I'm after. I'm trying to avoid specific selectors as I don't necessarily know what the element will be nested in.
DA
I would say that you should put a class on the elements. It is by far the least fragile approach to this problem.
Keith Rousseau
@Keith I'm positive that you are correct. I think forcing a change to the markup is the best option. That said, now I'm curious. So now I think this is more of a brain teaser than useful code. ;o)
DA
+1  A: 

Check out siblings() and :first.

F.Aquino
the catch is that they aren't siblings. However, if I knew the specific level of nesting, I could traverse back up, grab the siblings, then find(:first) within. In this scenario, though, I won't know the particular level of nesting for the first object I'm looking for.
DA
the <a>'s aren't siblings, but the <h3>'s your looking for are, but I can't quite figure out how this avoids the 2nd <a>
David
+1  A: 
$('a:first').parent().siblings().children('a');
Mark Schultheiss
That'd work if I knew the first anchor was nested only one element deep.
DA
The question is, does he want to work across parent elements? If not, this will work. If he had other `div > h3 > a` in this example and wanted to select those `a`, this wouldn't work.
Stuart Branham
Also, if the first `a` is right under his target `div`, this will break through that div return other stuff.
Stuart Branham
@DA, made that assumption based on your assumption comment.@Stuart B - yes, based this on his structure only
Mark Schultheiss
+3  A: 

Not a pure selector, but how about:

var depth = $('#myanchor').parents().length;
var all_at_depth = $("a").filter( function() { $(this).parents().length == depth; } );

You can use parentsUntil() to get the distance between #myanchor and a specific parent, if that helps.

jlew
I think that does help! Clever solution!
DA
A: 

How about this?

$(function () {
// I take it you need some way to get the reference element.
var referenceElement = $('a').eq(0);
// Build the selector by making as many child selectors as our nesting level.
var selector = '';
var currentElement = referenceElement;
while (currentElement[0].parentNode !== document.body) {
    selector = (selector ? '* > ' + selector : '*');
    window.console && window.console.debug(currentElement, '!==', document.body, ' => ', currentElement.parent(), '; selector = ', selector);
    currentElement = currentElement.parent();
}
// Replace the tagName stuff with '*' if you want any element to match.
selector = 'body > ' + selector + ' > ' + referenceElement[0].tagName;
window.console && window.console.log(selector, ' => ', $(selector));

});

janmoesen