从元素到根JS的HTML路径

时间:2015-05-27 09:11:12

标签: javascript html

例如,我有像这样的HTML

<body> 
   <div> 
     something. 
   </div> 
   <div> 
     something else 
   </div> 
   <div> 
     <a> something. </a>
     <a> ELEMENT </a> 
   </div> 
</body>

有没有办法通过使用JS获取从根到ELEMENT的路径,如下所示:

body[0]/div[2]/a[1]

因此,对于ELEMENT,需要查看父节点,检查是否存在具有相同标记的兄弟,然后正确分配值并以递归方式执行到root。

因此,对于ELEMENT来说,它是父根div的第二个(a[1])子节点,它是正文的第三个(div[2])子节点。

有什么办法可以用JS来完成吗?

3 个答案:

答案 0 :(得分:0)

这可能就是你要找的东西。我很抱歉,我很想念你的问题。

<html>
    <head>
        <script>
            //Recursive function to get element path until html from passed element e;
            function getPath(e, d){
                d = (d || []);

                //if (!e || e.tagName === 'BODY'){ //Body is obivous in most cases tho.
                if (!e || !e.parentNode){
                    return d.join('/');
                }
                else{
                    //j is needed since <head> is previous sibling to <body> :s
                    for (var i = 0, n = e, j = 0; n = n.previousElementSibling; i++) if (n.tagName === e.tagName) j++;

                    //Here we add the element to the current path \o/
                    d.push(e.tagName.toLowerCase() + '[' + j.toString() + ']');
                    return getPath(e.parentNode, d);
                };
            };
        </script>
    </head>

    <body onclick = 'alert(getPath(this));'>
        <div>something.</div> 
        <div>something else</div> 
        <div> 
            <a onclick = 'alert(getPath(this));'>something.</a>
            <a onclick = 'alert(getPath(this));'>ELEMENT</a> 
        </div> 
    </body>
</html>

答案 1 :(得分:0)

一种方法如下:

function findIndexOfLike(node) {
  // creating an Array of the filtered children of the node's
  // parent element (using Array.prototype.filter() with
  // Function.prototype.call() to apply the Array method
  // to the Array-like collection):
  var children = Array.prototype.filter.call(node.parentNode.children, function(child) {

    // keeping only those elements that are of the same
    // tagName:
    return node.tagName === child.tagName;
  });

  // Using Array.prototype.indexOf() to find the index of
  // the node from the array of children; and returning that:
  return children.indexOf(node);

}

function createIndexedPathTo(node) {

  // an empty Array to contain the path:
  var path = [],

    // initialising the 'current' variable, which we'll
    // use to move upwards through the document:
    current = node;

  // while the node contained in the 'current' variable is
  // not the <body> element:
  while (current.tagName.toLowerCase() !== 'body') {

    // we push the lower-cased tagName of the 'current' node,
    // along with its index, to the array:
    path.push(current.tagName.toLowerCase() + '[' + findIndexOfLike(current) + ']');

    // move the 'current' variable to the parentNode of
    // the current element (to move 'up'):
    current = current.parentNode;
  }

  // there can be only one <body> element, but since
  // you seem to want it listed we add it here:
  path.push('body[0]');

  // now we reverse the array, and join it together,
  // with the '/' character, to form a string, returning
  // that formed string:
  return path.reverse().join('/');
}

// calling the function, passing it a DOM Node from which to start:
var route = createIndexedPathTo(document.querySelector('a:nth-child(2)'));

// setting the 'data-routeto' attribute of the <body>
// in order to display that route/path in the document
// using CSS generated content:
document.body.dataset.routeto = route;

&#13;
&#13;
function findIndexOfLike(node) {
  var children = Array.prototype.filter.call(node.parentNode.children, function(child) {
    return node.tagName === child.tagName;
  });
  return children.indexOf(node);

}

function createIndexedPathTo(node) {
  var path = [],
    current = node;
  while (current.tagName.toLowerCase() !== 'body') {
    path.push(current.tagName.toLowerCase() + '[' + findIndexOfLike(current) + ']');
    current = current.parentNode;
  }
  path.push('body[0]');
  return path.reverse().join('/');
}

var route = createIndexedPathTo(document.querySelector('a:nth-child(2)'));

document.body.dataset.routeto = route;
&#13;
body::before {
  display: block;
  content: 'Route to "Example" element: ' attr(data-routeto);
  color: #999;
}
&#13;
<div>something.</div>
<div>something else</div>
<div> <a> something. </a>
  <a id="demo"> ELEMENT </a> 
</div>
&#13;
&#13;
&#13;

外部JS Fiddle demo,用于实验。

参考文献:

答案 2 :(得分:-1)

function Foo() { 
    return this; 
}

var a = Foo();       //returns window object
var b = new Foo();   //returns empty object of foo

a instanceof Window;  // true
a instanceof Foo;     // false

b instanceof Window;  // false
b instanceof Foo;     // true