views:

877

answers:

5

Given the following HTML:

<p><img id="one" alt="at beginning, return true" />Some Text</p>
<p>Some <img id="two" alt="in middle, return false" />Text</p>
<p>Some Text<img id="three" alt="at end, return false" /></p>

How would I be able to tell that $("img#one") is at the beginning of its parent node?

Ideally what I'm trying to do is this:

$("p>img").each(function () {
    var $this = $(this);
    var $parent = $this.parent();
    if ("$this is at the beginning of $parent.html()") {
        $parent.before($this);
    } else {
        $parent.after($this);
    }
});

Edit: with sebasgo's help, here's the final code and result:

$("p>img").each(function () {
    var $this = $(this);
    var $parent = $this.parent();
    if (this == this.parentNode.firstChild) {
        $parent.before($this);
    } else {
        $parent.after($this);
    }
});

<img id="one" alt="at beginning, return true" />
<p>Some Text</p>
<p>Some Text</p>
<img id="two" alt="in middle, return false" />
<p>Some Text</p>
<img id="three" alt="at end, return false" />
A: 

Have a look at the :first-child jQuery selector. Given the element, use the :parent selector to get the parent, then check for equality between the parent's first child and the element in question.

Matt Ball
I just tried :first-child and it is true for all 3 cases.
travis
+1  A: 

Use

var elem = $("img#one").get(0)
if (elem.parentNode.firstChild == elem)
{ .... }

Hope this works better.

sebasgo
I just tried :first-child and it is true for all 3 cases.
travis
As I see jQuery ignores text nodes in its selector engine. Then you schould use plain javascript:var elem = document.getElementById("#one");if (elem == elem.parentNode.firstChild) {...}
sebasgo
perfect thanks! since I'm in a .each() I went with (this == this.parentNode.firstChild)
travis
A: 

Try this condition:

($parent.contents().eq(0).attr("id") === $this.attr("id"))
Andreas Grech
A: 

From similar question on SO.

http://stackoverflow.com/questions/562134/jquery-how-to-match-first-child-of-an-element-only-if-its-not-preceeded-by-a-te

$("p>img").each(function () {
    var prev = this.previousSibling;
    var isThisTheFirstNode = $(this).parent().html().toUpperCase().indexOf('<IMG>') == 0;

    var method = isThisTheFirstNode ? 'before' : 'after';
    $(this).parent[method].before(this);
});
SolutionYogi
A: 

The following code will tell you if the node in question is the 'first-child' or not so should work for you. I've just been battling with a similar problem and this worked for me.

if($(this).prev().length)
{
    // Not first-child
} else {
    // is first-child
}
chrismacp
That doesn't take text nodes into account though.
travis
Ah yes, maybe it wont help you! The text is not actually a child of the paragraph.
chrismacp