tags:

views:

63

answers:

3

Given two DOM elements, say a and b, how can we determine which comes first in the document?

I'm implementing drag and drop for a set of elements. And the elements can be selected in any order, but when they are dragged, these elements need to be moved in the "correct" order.

+1  A: 

I think the easiest way is to give them both something common that can be easily looked up. For instance, if they both have the same name attribute, you can use getElementsByName, which will return a collection of the elements in the order they appear in the document:

var els = document.getElementsByName("myName");

Here els[0] would contain the first element of the document, els[1] would contain the second.

Using selectors, you could achieve the same thing by using the combining , selector separator:

var els = document.querySelectorAll("#el1, #el2");

The only downside is that querySelectorAll() is only supported by newer browsers (so IE6/7 are ruled out). The alternative is to use a framework like jQuery:

var els = $("#el1, #el2");
Andy E
That makes the presumption that the two elements he is comparing are of the same tag name.
@austin cheney: You're confusing `getElementsByName` with `getElementsByTagName`. `getElementsByName` retrieves all elements with the same name attribute, e.g. `<a name="someName">Hello</a>`. also, I added other alternatives.
Andy E
Only a minority of elements are allowed to have a name attribute.
RoToRa
getElementsByTagName creates an array of all elements with the specified tag name. If the op needs to compare two elements of the same tag name then that method will not work since both elements will be equivocally contained within the specified array. In other words the getElementsByTagName does not apply sufficient disambiguation between two div elements, for instance.
@Austin Cheney: Which is why I didn't recommend `getElementsByTagName` to begin with, what's your point?
Andy E
@RoToRa: `getElementsByName` was intended to be an example, any method that returns a collection containing both nodes could have their indices in that collection compared to discover which element precedes the other.
Andy E
A: 

Your logical method is extremely inefficient. You are attempting to count every node in the DOM tree and then find the position of two of those nodes and make a determination of their position relative to each other.

It would be far more efficient to determine the position of a node relative to a parent or grandparent node and then use that relationship as your basis of comparison instead of a simple count.

+2  A: 

What you're looking for is compareDocumentPosition. PPK has browser compatibility details and John Resig has a version for IE.

Jeffery To