Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Is there a means of detecting whether an element appears before or after another element in markup? This is regardless of position in DOM. It could be a child, a sibling, a parent or a parent's parent. This is a general question, so no markup to share.

To clarify - this is in regards to the element's position in markup, not its display position. Now that I think about it my question is a bit strange because if you have element X and element Y then you can have these scenarios.

//in regards to y
<x />
<y /> //:after

<y /> //:before
<x />

<x><y /></x> //not really before or after is it?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
153 views
Welcome To Ask or Share your Answers For Others

1 Answer

Yes, sort of. DOM3 introduced Node.compareDocumentPosition, which allows you to compare the position of two elements. The functionality isn't very friendly: it involves bitmasks: this is a jQuery plugin that should simplify its use.

This code is only tested on Firefox 9 and the current version of Chromium. Certainly it won't work in old versions of IE.

$.fn.docPosition = function(element) {
    if (element.jquery) element = element[0];

    var position = this[0].compareDocumentPosition(element);

    if (position & 0x04) return 'after';
    if (position & 0x02) return 'before';
};

Also, an element that contains another is considered to be before it in the structure.


OK, a little Googling gives me this blog post by John Resig (the creator of jQuery), which includes compatibility with IE <9. (It's a little ugly: it uses two non-standard bits of functionality: contains and sourceIndex.) This code should be cross-browser:

$.fn.docPosition = function (element) {
    function comparePosition(a, b) {
        return a.compareDocumentPosition ? 
          a.compareDocumentPosition(b) : 
          a.contains ? 
            (a != b && a.contains(b) && 16) + 
              (a != b && b.contains(a) && 8) + 
              (a.sourceIndex >= 0 && b.sourceIndex >= 0 ?
                (a.sourceIndex < b.sourceIndex && 4) + 
                  (a.sourceIndex > b.sourceIndex && 2) :
                1)
            + 0 : 0;
    }

    if (element.jquery) element = element[0];

    var position = comparePosition(this[0], element);

    if (position & 0x04) return 'after';
    if (position & 0x02) return 'before';
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...