tags:

views:

61

answers:

4

I know this has been asked numerous times, and I have tried all the suggestions, and read all about varying selectors, and etc. but nothing is working for me

given the following piece of HTML:

<div class="class1">
<p><a>link</a></p>       

<div class="class2 class3">
<p><font><a>link2</a></font></p>


</div></div>

I want to select the first div's <a> tag, but nothing from the second div

I have tried:

$('.class1').not('.class2, .class3')
$('.class1').not('.class2')
$('.class1').not('.class3')
$(".class1:not(.class2)")
$(".class1:not(.class3)")
$(".class1:not(.class2, .class3)")
$("div.class1:not(.class2)")
$("div.class1:not(div.class2)")
$("div.class1:not(div.*)")

etc.

I don't know if it's because the second div has two class names, or because the second div's <a> tags are not direct children of the second div (e.g. there are font tags and such around them) but I am unable to exclude the second div.

+5  A: 

Have you tried the child selector > ?

div.class1 > p > a

will select only immediate descendants of class1.

If you need a broader rule, I think you just need to add a space in one of your examples:

$(".class1 :not(.class2) a")

Update from the comments: This works:

$(".class1 > :not(.class2.class3) a").css('border','1px solid red');
Pekka
`:not(.class2)` can match the `<p>` tag, so I'm pretty sure that wouldn't work.
Kobi
@Kobi it should stop at the `class2` div. Haven't worked much with this though so I don't know for sure
Pekka
$(".class1 :not(.class2 .class3)") breaks the whole thing, and using one or the other of class2/class3 does not exclude the second div
null
@Gert G good to know! @null how about `:not(.class2.class3)`? That would be the correct notation.
Pekka
$(".class1 :not(.class2.class3)") does not exclude div class="class2 class3"
null
@Gert thanks! If the `.class2.class3` div is always an immediate descendant of `class1`, this should work: `$(".class1 > :not(.class2.class3) a").css('border','1px solid red');`
Pekka
+2  A: 

Well, this depends on your exact needs, but this can work - it selects the div, the <p> directly under it, and then the link in it:

$('.class1 > p a')

To find all links except those nested in another <div>, you can try something like:

var class1 = $(".class1");
var badLinks = class1.find('div a'); // or .class2 a, .class3 a
var goodLinks = class1.find('a[href$=jpg]').not(badLinks);

That finds all links in your class, and remove the links that contained within another <div>, in any level. You write that a bit shorter, it you will, using:

class1.find('a[href$=jpg]').not(class1.find('div a'));
Kobi
The content is dynamic, and the children of class1 can be any html tag aside from another divbut i might be able to work something out with that
null
@null - if the structure is complex, you may want something like: http://stackoverflow.com/questions/3096098/jquery-filtering-selector-to-remove-nested-elements-matching-pattern
Kobi
to further complicate it, i'm not just taking any a tag, i'm using .find('a[href$=".jpg"]') after selecting the div class i want the a tag from
null
okay$('.class1 > p').find('a[href$=".jpg"]') works correctly when the first child of .class1 is pis there a method to iterate through a given array of tags and their children as well, including everything, and all permutations except for any children that are divs?
null
@kobi, the problem with this latest revision, is it wont pickup class1.find('div p') which contains a link that i dont want included
null
@null - you've said nothing about excluding a `<p>` `:/`. I think you should update your question and include better examples of what yo want to match. Look at the question I linked above: the OP has many examples.
Kobi
The original question even has <p> in the examplethe inner div can contain any number of child elements, simply checking for 'div a' will not find the a tags that are nested further within that div
null
@null - your example has `<p>` around both links. Are we expected to ignore one, but not the other? `:)`
Kobi
+1  A: 

If you use the child selector E > F rather than the descendant selector E F in combination with the element names, you will only get the desired element, e.g.:

.class1 > p > a
Gumbo
A: 

well, finally worked out an acceptable solution

$('.class1').find('a[href$=".jpg"],a[href$=".png"],a[href$=".gif"]').each(function(){
if($(this).parents('div').attr('class') == 'class1'){do whatever}});

nothing else was working for me. thanks for the help though, many of the answers here would have worked but the first div could contain any number of child elements (or none at all) before the second div, and the second div could contain any number of child elements before the a tag that i was trying to filter out

null