5

Say I've selected a span tag in a large html document. If I treat the entire html document as a big nested array, I can find the position of the span tag through array indexes. How can I output the index path to that span tag? eg: 1,2,0,12,7 using JavaScript.

Also, how can I select the span tag by going through the index path?

Rana
  • 4,431
  • 9
  • 32
  • 39

4 Answers4

8

This will work. It returns the path as an array instead of a string.

Updated per your request.

You can check it out here: http://jsbin.com/isata5/edit (hit preview)

// get a node's index.
function getIndex (node) {
  var parent=node.parentElement||node.parentNode, i=-1, child;
  while (parent && (child=parent.childNodes[++i])) if (child==node) return i;
  return -1;
}

// get a node's path.
function getPath (node) {
  var parent, path=[], index=getIndex(node);
  (parent=node.parentElement||node.parentNode) && (path=getPath(parent));
  index > -1 && path.push(index);
  return path;
}

// get a node from a path.
function getNode (path) {
  var node=document.documentElement, i=0, index;
  while ((index=path[++i]) > -1) node=node.childNodes[index];
  return node;
}

This example should work on this page in your console.

var testNode=document.getElementById('comment-4007919');
console.log("testNode: " + testNode.innerHTML);

var testPath=getPath(testNode);
console.log("testPath: " + testPath);

var testFind=getNode(testPath);
console.log("testFind: " + testFind.innerHTML);
Dagg Nabbit
  • 75,346
  • 19
  • 113
  • 141
  • thanks for the answer. How would I get the object/element from the path? // 0,1,16,1,0,3 – Rana Sep 24 '10 at 01:57
  • you could get it by recursively finding someNode.`childNodes`[pathIndex], where someNode starts out as the document element (`window.document.documentElement`). I'll update the answer in a minute. – Dagg Nabbit Sep 24 '10 at 02:19
  • thanks for the update. have another question. why node.parentElement || node.parentNode? whats the difference between them? – Rana Sep 24 '10 at 02:51
  • You can probably just use parentNode, it's an old habit I use because some old browser or other would only accept non-standard parentElement, but it's probably long gone. Most browsers accept either one; moz only accepts parentNode I think, which is the standard. – Dagg Nabbit Sep 24 '10 at 02:54
0

Using jquery:

var tag = $('#myspan_id');
var index_path = [];
while(tag) {
  index_path.push(tag.index());
  tag = tag.parent();
}
index_path = index_path.reverse();
ggarber
  • 8,300
  • 5
  • 27
  • 32
0

Using the DOM

node = /*Your span element*/;
var currentNode = node;
var branch = [];
var cn; /*Stores a Nodelist of the current parent node's children*/
var i;
while (currentNode.parentNode !== null)
    {
    cn = currentNode.parentNode.childNodes;
    for (i=0;i<cn.length;i++)
        {
        if (cn[i] === currentNode)
            {
            branch.push(i);
            break;
            }
        }
    currentNode = currentNode.parentNode;
    }
cn = document.childNodes;
for (i=0;i<cn.length;i++)
    {
    if (cn[i] === currentNode)
        {
        branch.push(i);
        break;
        }
    }
node.innerHTML = branch.reverse().join(",");
Randy the Dev
  • 25,810
  • 6
  • 43
  • 54
0

composedPath for native event.

(function (E, d, w) {
    if (!E.composedPath) {
      E.composedPath = function () {
        if (this.path) {
          return this.path;
        }
        var target = this.target;

        this.path = [];
        while (target.parentNode !== null) {
          this.path.push(target);
          target = target.parentNode;
        }
        this.path.push(d, w);
        return this.path;
      };
    }
  })(Event.prototype, document, window);

use:

var path = event.composedPath()
Yoel Duran
  • 381
  • 3
  • 5