This is a function that takes a DOM node, and returns the offset of that node. What's the "offset" ? It's the ordinal number in its siblings, the number "n" of node.parentNode.childNodes[n]. Sadly there's no easy way to do this with DOM API, basically it's just iterating over all its siblings and keep counting.

getNodeOffset = function(node) { var p = node.parentNode; if (p == null) return; for (var i = 0, l = p.childNodes.length; i < l ; i++ ) { if (p.childNodes[i] == node) break;+ } return i; }

Here's one other interesting function, I called it "getNodeCoordination". Since each node must have a parent node, it can always be traced all the way up to document.body. This forms a simple coordination system. You can use a list of numbers like:

[3,0,0,1]

To uniquely locate a node. The example above can be translated into this horrible English: "The 1st child of the 0th child of the 0th child of the 3rd child of document.body". Or this elegant XPath representation:

//body/*[4]/*[1]/*[1]/*[2]

Those numbers are offset by one for obvious reason. Here's the code of that "getNodeCoordation" function.

getNodeCoordination = function(node, baseNode) { if (baseNode == null) baseNode = window.document.body; var coord = []; var p = node; while (p != baseNode) { var offset = getNodeOffset(p); if (offset == null) break; coord.unshift(offset); p = p.parentNode; } if (p != baseNode) return null; return coord; }

Obviously the return value is very fragile against DOM change. Any DOM modification can invalid a previously stored coordination value. However, If you ever need to bookmark the location of a node and serialize it for storage, this is one approach.

ps. This is a cross-post from handlino.com

Labels: dom, handlino, javascript