views:

188

answers:

4

I'm trying to dynamically style some elements on my pages. So, if I had the following code:

<a href="#">
  Select Me
</a>

<a href="#">
  <img src="blah.jpg" />
  Don't select me
</a>

<a href="#">
 <div>Don't select me either</div>
 <img src="blah.jpg" />
</a>

<a href="#">
  <div>You can select me too.</div>
</a>

I would like it to select the first and fourth tags.

From what I could tell, by using:

 $("a:first-child")

Won't select the first tag because it doesn't have any children (just text). The second tag should not get selected so something like:

$("a:first-child").not("img)

but that leaves out the first item.

EDIT: If there is an IMG anywhere in the A element, don't select it.

A: 

do you wanna select the first anchor?

$("a:first")

coolnalu
that just selects the first link, which is nothing at all like what was asked for.
nickf
+3  A: 

Assuming I've understood your question properly,

$("a:not(:has(img))");

http://api.jquery.com/not-selector/
http://api.jquery.com/has-selector/


After your comments below, the selector I wrote originally should work for you.

Andy E
that'll skip links where the image is not the first child.
nickf
@nickf: ah, I did read it wrong (and it appears you did too).
Andy E
I think he wanted that only the first child could not be an img. This code would filter also a's that have img not as first child.
Dom De Felice
@Andy: oh, how is my answer wrong?
nickf
You are all right, but after looking at it a little more, I don't think that will be an issue. I want to style the links but not style anything that has an image inside of the A. I will edit the question to be more clear.
hacker
@nickf: it's not, sorry, I misread your answer too. Lets put it down to sleep deprivation and I'll +1 your answer :-)
Andy E
@Andy - lol, yes I should go to bed too... 1:30am here..
nickf
@nickf: 16:37 here LOL. And it appears that by changing the requirements of his answer, my selector is perfect for the job ;-)
Andy E
+6  A: 

If you want to select all links which don't have an image as the first child, use this:

$('a:not(:has(> img:first-child))')

If you want to select all links which don't have an image at all, use this:

$('a:not(:has(img))')
nickf
I think this will work, but it makes my head hurt to reason about it. The documentation for has says the element is included if "any of its descendants match the selector", but doesn't restrict it to direct descendants. Do you know if this would match if there was an image inside one of the anchor's direct descendants?
tvanfosson
Meh, copycat ;-P
Andy E
tvanfosson: in fact *has* works that way, but as you can see, the next selector starts with > that means "children" (direct descendants).
Dom De Felice
+1  A: 

I have not tried it, but you should write something like this:

$("a").filter(function() {
    return $(this).filter("> img:first-child").length != 0;
})

It will first select all the a's and then filter the ones that have an img as first child.

UPDATE:
nickf solution is definitely clearer :-)
I often forget how versatile the jquery selector is.

Dom De Felice