#javascript #html #dom
#javascript #HTML #dom
Вопрос:
У меня есть следующая разметка HTML:
<body>
<div class="wrapper">
<div class="head">
<p class="title">title</p>
<a href="#" class="logo"></a>
</div>
</div>
</body
Мне нужно получить что-то вроде следующего — элемент «A» с классом «logo» является вторым дочерним узлом элемента div с классом «head». Элемент div с классом «head» является первым дочерним узлом элемента div с классом «wrapper», элемент div с классом «wrapper» является первым дочерним узлом body. Тогда я бы получил местоположение ссылки с классом «logo» следующим образом:
var a = [1, 1, 2]
Итак, если я пойду в противоположном направлении, используя приведенный выше массив, я найду ссылку с классом «logo» в DOM, начиная с элемента body. Кто-нибудь может сказать мне, как этого можно достичь с помощью JavaScript?
Заранее спасибо.
Комментарии:
1. Вы должны знать, что пробелы между узлами элементов в большинстве реализаций приводят к тому, что текстовые узлы существуют как дополнительные дочерние узлы. например, в вашем примере div class=»head» имеет текстовый дочерний узел, дочерний узел элемента, текстовый дочерний узел, дочерний узел элемента и текстовый дочерний узел в большинствереализации. Поэтому попытка индексировать узлы элементов в
childNodes
коллекции может быть сложнее, чем вы думаете в настоящее время. Однако в наши дни существуетchildren
коллекция, которая содержит только дочерние узлы элементов, поэтому в зависимости от ваших потребностей вы можете рассмотреть возможность использования этой коллекции.2. Спасибо. Есть примеры? Я просто не могу понять, как это можно подсчитать.
3. @cycero вы не можете. Вам следует избегать предположений о позиции в
.childNodes
на основе HTML.
Ответ №1:
Вот пара функций, адаптированных из некоторого существующего моего кода, чтобы превратить узел в массив вложенных позиций внутри узла и обратно.
Живая демонстрация: http://jsfiddle.net/DSNUv /
Код:
function getNodeIndex(node) {
var i = 0;
while( (node = node.previousSibling) ) {
i ;
}
return i;
}
function nodeToPath(node, rootNode) {
var path = [], n = node;
rootNode = rootNode || document.documentElement;
while (n amp;amp; n != rootNode) {
path.push(getNodeIndex(n));
n = n.parentNode;
}
return path;
}
function pathToNode(path, rootNode) {
rootNode = rootNode || document.documentElement;
var node = rootNode;
var i = path.length, nodeIndex;
while (i--) {
nodeIndex = path[i];
if (nodeIndex < node.childNodes.length) {
node = node.childNodes[nodeIndex];
} else {
throw new Error("Child node index out of range: " nodeIndex);
}
}
return node;
}
Пример использования:
var a = document.getElementsByTagName("a")[0];
var path = nodeToPath(a, document.body);
alert(path);
var el = pathToNode(path, document.body);
alert(el.className);
Ответ №2:
Учитывая следующий HTML:
<body>
<div class="wrapper">
<div class="head">
<p class="title">title</p>
<a href="#" class="logo"></a>
</div>
</div>
</body
var el = document.body; // body
var div = document.body.firstChild; // div.wrapper
el === div.parentNode; // body === body
var div2 = div.firstElementChild; // div.head
div2.parentNode.parentNode === el; // body === body
var p = div2.firstElementChild; // p.title
var a = p.nextElementSibling; // a.logo
div2.children[1] === a; // a === a
Я не совсем уверен, чего вы пытаетесь достичь. Но я рекомендую вам просто ходить по дереву, а не создавать отношения в каком-то массиве.