Войти через VK Войти через FB Войти через Google Войти через Яндекс
Поиск по сайту
Быстрый поиск элементов DOM
В новых браузерах для перемещения по DOM-дереву появилась возможность использовать интерфейс <Element Traversal>, который позволяет искать элементы, исключая текстовые узлы так, как это происходит в Internet Explorer при использовании стандартных firstChild, lastChild, nextSibling и previousSibling, что увеличивает скорость поиска элементов.
В браузерах, поддерживающих "Element Traversal", доступны новые методы:
- firstElementChild - первый дочерний элементы;
- lastElementChild - последний дочерний элементы;
- nextElementSibling - следующий элементы;
- previousElementSibling - предыдущий элементы;
- childElementCount - количество дочерних элементов.
Эти методы работают с узлами, у которых nodeType == 1, например, метод childElementCount показывает не сколько всего дочерних узлов, а количество дочерних элементов, т.е. узлов с nodeType == 1.
Все конечно хорошо и удобно, но нельзя забывать о огромной армии пользователей старых браузеров, поэтому напишем функции, которые позволят кросс-браузерно выполнять поиск дочерних элементов.
Для начала проверим, поддерживает ли браузер интерфейс "Element Traversal".
var traversal = typeof document.createElement('div').childElementCount != 'undefined';
В итоге переменная traversal будет иметь значение true или false, опираясь на которое мы будем выбирать, какой из способов перемещения по DOM-дереву использовать.
Следующая функция будет искать первый дочерний элемент:
var firstChild = traversal ? function(node) {
// для новых браузеров достаточно
// воспользоваться встроенным методом
return node.firstElementChild;
} : function(node) {
// для старых браузеров
// находим первый дочерний узел
node = node.firstChild;
// ищем в цикле следующий узел,
// пока не встретим элемент с nodeType == 1
while(node && node.nodeType != 1) node = node.nextSibling;
// возвращаем результат
return node;
};
Рассмотрим простой пример использования:
<div id="test">
text node
<div>First</div>
text node
<div>Last</div>
text node
</div>
<script>
var node = document.getElementById('test');
var text = firstChild(node).innerHTML;
alert(text); // First
</script>
Аналогично будет выглядет функция lastChild:
var lastChild = traversal ? function(node) {
return node.lastElementChild;
} : function(node) {
node = node.lastChild;
while(node && node.nodeType != 1) node = node.previousSibling;
return node;
};
Используем:
text = lastChild(node).innerHTML;
alert(text); // Last
Назовем функции поиска следующего и предыдущего элемента next и previous соответственно:
var next = traversal ? function(node) {
return node.nextElementSibling;
} : function(node) {
while(node = node.nextSibling) if(node.nodeType == 1) break;
return node;
};
var previous = traversal ? function(node) {
return node.previousElementSibling;
} : function(node) {
while(node = node.previousSibling) if(node.nodeType == 1) break;
return node;
};
И рассмотрим их работу на простеньком примере:
<div>
text node
<div id="first">First</div>
text node
<div id="last">Last</div>
text node
</div>
<script>
var text = next(node).innerHTML;
alert(text); // Last
node = document.getElementById('last');
text = previous(node).innerHTML;
alert(text); // First
</script>
Чтобы получить коллекцию дочерних узлов, среди которых могут содержаться, ненужные нам текстовые узлы, в интерфейсе DOM предусмотрен метод childNodes, но большинство браузеров поддерживает и более удобный метод children, который возвращает коллекцию, состоящую только из элементов.
Проверим, поддерживает ли браузер метод children?
var children = typeof document.createElement('div').children != 'undefined';
И напишем функцию поиска:
var child = children ? function(node) {
return node.children;
} : function(node) {
var list = node.childNodes,
length = list.length,
i = -1,
array = [];
while(++i < length)
if(list[i].nodeType == 1)
array.push(list[i]);
return array;
};
Ну и конечно, рассмотрим работу на примере:
<div id="test">
text node
<div>First</div>
text node
<div>Last</div>
text node
</div>
<script language=JavaScript>
var node = document.getElementById('test');
var count = child(node).length;
alert(count); // 2
</script>
Все эти методы, но в более функциональном виде, используются в новых версиях JavaScript фреймворка js-core. А также для поиска всех дочерних элементов по имени CSS-класса, атрибутам или просто по имени тега, когда это возможно, используется "Selectors API", что позволяет добиться хороших результатов в тестах на производительность.
.
Прокомментировать/Отблагодарить