Навигация по дереву DOM
171Веб-программирование --- jQuery --- Навигация по дереву DOM
»» В данной статье используется исходный код для примеров. Сохраните эту страницу для тестирования приведенных ниже примеров.
Выбранный набор элементов можно использовать в качестве отправной точки для перемещения к другим узлам DOM-дерева. При этом, по сути, один набор элементов используется для создания другого набора. Описанию и демонстрации применения методов jQuery, предназначенных для обхода структуры DOM, посвящены следующие разделы. В них рассматриваются различные типы отношений, которые могут существовать между содержащимися в документе элементами.
Каждый из описанных в последующих разделах методов возвращает объект jQuery. Этот объект может как содержать подходящие объекты, если таковые имеются, так и быть пустым в случае их отсутствия (свойство length таких объектов возвращает нулевое значение).
Перемещение вниз по дереву DOM
Процесс перемещения вниз по иерархической структуре DOM связан с выбором дочерних элементов (непосредственных потомков), а также всех остальных элементов, являющихся потомками элементов, содержащихся в объекте jQuery. Соответствующие методы jQuery и их краткое описание приведены в таблице ниже:
Метод | Описание |
---|---|
children() | Выбирает дочерние элементы всех элементов, содержащихся в объекте jQuery |
children(селектор) | Выбирает все элементы, которые соответствуют указанному селектору и при этом являются непосредственными потомками элементов, содержащихся в объекте jQuery |
contents() | Возвращает дочерние элементы и текстовое содержимое всех элементов, содержащихся в объекте jQuery |
find() | Выбирает потомки элементов, содержащихся в объекте jQuery |
find(селектор) | Выбирает элементы, которые соответствуют указанному селектору и при этом являются потомками элементов, содержащихся в объекте jQuery |
find(jQuery), find(HTMLElement), find(HTMLElement[]) |
Выбирает пересечение множества непосредственных потомков элементов, содержащихся в объекте jQuery, и множества элементов, содержащихся в объекте аргумента |
Метод children() выбирает лишь те элементы, которые являются непосредственными потомками (дочерними элементами) элементов, содержащихся в объекте jQuery, и может принимать селектор в качестве необязательного аргумента, обеспечивающего дополнительную фильтрацию элементов. Метод find() предназначен для выбора всех потомков, а не только дочерних элементов. Метод contents() наряду с дочерними элементами возвращает также текстовое содержимое.
Пример использования методов children() и find() приведен ниже:
$(function() {
var childCount = $('div.drow').children().each(function(index, elem) {
console.log("Дочерний элемент: " + elem.tagName + " " + elem.className);
}).length;
console.log("Всего имеется " + childCount + " дочерних элементов");
var descCount = $('div.drow').find('img').each(function(index, elem) {
console.log("Потомок: " + elem.tagName + " " + elem.src);
}).length;
console.log("Всего имеется " + descCount + " элементов-потомков img");
});
В этом примере метод children() используется без селектора, тогда как метод find() используется с одним селектором. Подробная информация о выбранных элементах выводится на консоль вместе с указанием их количества:
Среди приятных особенностей методов children() и find() можно отметить отсутствие дублирования элементов в выбранном наборе. Это подтверждает пример, приведенный ниже:
$(function() {
$('div.drow').add('div.dcell').find('img').each(function(index, elem) {
console.log("Потомок: " + elem.tagName + " " + elem.src);
});
});
В этом примере мы начинаем с того, что создаем объект jQuery, который содержит все элементы div с классом drow и все элементы div с классом dcell. Ключевым моментом здесь является то, что все элементы, принадлежащие классу dcell, одновременно являются элементами класса drow. Это означает, что мы имеем дело с двумя перекрывающимися множествами элементов-потомков, и в случае использования метода find() с селектором img это могло бы привести к дублированию элементов в результирующем наборе, поскольку элементы img являются потомками элементов div обоих классов. Однако jQuery выручает нас и самостоятельно заботится о том, чтобы среди возвращаемых элементов дублирование отсутствовало, что подтверждается результатами, выводимыми на консоль:
Перемещение вверх по дереву DOM
Перемещению вверх по DOM-дереву соответствует поиск родителей и предков элементов, содержащихся в объекте jQuery. Методы, используемые для таких перемещений, приведены в таблице ниже:
Описание | Метод |
---|---|
closest(селектор), closest(селектор, контекст) | Выбор ближайшего предка, соответствующего указанному селектору, для каждого элемента, содержащегося в объекте jQuery |
closest(jQuery), closest(HTMLElement) | Выбор ближайшего предка для каждого элемента в объекте jQuery, совпадающего с одним из элементов, содержащихся в объекте аргумента |
offsetParent() | Нахождение ближайшего предка, значением CSS-свойства position которого является fixed, absolute или relative |
parent(), parent(селектор) | Выбор непосредственных предков для каждого элемента в объекте jQuery с возможностью их фильтрации с помощью селектора |
parents(), parents(селектор) | Выбор предков для каждого элемента в объекте jQuery с возможностью их фильтрации с помощью селектора |
parentsUntil(селектор), parentsUntil(селектор, селектор) | Выбор предков для каждого элемента в объекте jQuery до тех пор, пока не встретится элемент, соответствующий селектору. Результаты могут фильтроваться посредством второго селектора |
parentsUntil(HTMLElement), parentsUntil(HTMLElement, селектор), parentsUntil(HTMLElement[]), parentsUntil(HTMLElement[], селектор) | Выбирает предков для каждого элемента в объекте jQuery до тех пор, пока не встретится один из указанных элементов. Результаты могут фильтроваться посредством второго селектора |
Выбор родительских элементов
Метод parent() позволяет выбрать родительский элемент для каждого из элементов, содержащихся в объекте jQuery. Если методу предоставляется селектор, то в результирующий набор будут включаться только те родительские элементы, которые соответствуют селектору. Пример использования метода parent() приведен ниже:
$(function() {
$('div.dcell').parent().each(function(index, elem) {
console.log("Элемент: " + elem.tagName + " " + elem.id);
});
$('div.dcell').parent('#row1').each(function(index, elem) {
console.log("Отфильтрованный элемент: " + elem.tagName + " " + elem.id);
});
});
В этом сценарии сначала выбираются все элементы div, принадлежащие классу dcell, а затем вызывается метод parent(), выбирающий все родительские элементы. Здесь также демонстрируется использование метода parent() с селектором. Подробная информация о каждом выбранном родительском элементе выводится на консоль с использованием метода each:
Выбор предков
Метод parents() (обратите внимание на последнюю букву s в его названии) обеспечивает возможность выбора всех, а не только непосредственных предков (родителей) элементов, содержащихся в объекте jQuery. Как и в предыдущем случае, метод может принимать в качестве аргумента селектор для фильтрации результатов.
Пример использования метода parents() приведен ниже:
$(function() {
$('img[src*=peony], img[src*=rose]').parents().each(function(index, elem) {
console.log("Элемент: " + elem.tagName + " " + elem.className + " "
+ elem.id);
});
});
В этом примере метод parents() используется для выбора предков двух предварительно выбранных элементов img. Информация о каждом предке выводится на консоль:
Метод parentsUntil() является еще одной разновидностью методов, предназначенных для выбора предков элементов. Для каждого из элементов, содержащихся в объекте jQuery, метод parentsUntil() осуществляет перемещение вверх по иерархической структуре DOM, выбирая элементы-предки до тех пор, пока не встретится элемент, соответствующий селектору. Пример использования этого метода приведен ниже:
$(function() {
$('img[src*=peony], img[src*=rose]').parentsUntil('form')
.each(function(index, elem) {
console.log("Элемент: " + elem.tagName + " " + elem.className
+ " " + elem.id);
});
});
В этом примере процесс выбора предков для каждого элемента продолжается до тех пор, пока не встретится элемент form. На консоль выводится следующий результат:
Обратите внимание, что элементы, соответствующие селектору, исключаются из состава выбираемых предков. В данном случае это означает исключение элемента form. Набор предков можно подвергнуть дополнительной фильтрации, предоставив методу paraentsUntil() селектор в качестве второго аргумента, как показано в примере ниже:
$(function() {
$('img[src*=peony], img[src*=rose]').parentsUntil('form', ':not(.dcell)')
.each(function(index, elem) {
console.log("Элемент: " + elem.tagName + " " + elem.className
+ " " + elem.id);
});
});
В этом примере добавлен селектор, который фильтрует элементы, принадлежащие классу dcell. На консоль выводится следующий результат:
Выбор первого подходящего предка
Метод closest() позволяет выбирать первого из предков, соответствующих селектору, для каждого элемента в объекте jQuery. Пример использования этого метода приведен ниже:
$(function() {
$('img').closest('.drow').each(function(index, elem) {
console.log("Элемент: " + elem.tagName + " " + elem.className
+ " " + elem.id);
});
var contextElem = document.getElementById("row1");
$('img').closest('.drow', contextElem).each(function(index, elem) {
console.log("Контекстный элемент: " + elem.tagName + " " + elem.className
+ " " + elem.id);
});
});
В этом примере мы сначала выбираем элементы img в документе, а затем находим для каждого из них с помощью метода closest() ближайшего предка, который принадлежит классу drow.
Область выбора предков можно сузить, передав методу closest() объект HTMLElement() в качестве второго аргумента. Те предки, которые не являются контекстным объектом или его потомками, не включаются в выбранный набор. На консоль выводится следующий результат:
Методу closest() также можно передать в качестве аргумента объект jQuery, объект HTMLElement или массив объектов HTMLElement. В этом случае метод closest() будет продолжать процесс выбора предков для каждого из элементов, содержащихся в исходном объекте jQuery, до тех пор пока не встретится объект, переданный в качестве аргумента.
Метод offsetParent() представляет собой вариацию на тему метода closest() и предназначен для нахождения первого потомка, значение CSS-свойства position которого равно relative, absolute или fixed. Такие элементы называются позиционированными предками, и их поиск может оказаться полезным при работе с анимацией. Пример использования этого метода приведен ниже:
<style type="text/css">
#row1 {position: fixed; top: 75px; left: 50px}
#row2 {position: fixed; top: 150px; left: 50px}
</style>
<script type="text/javascript">
$(function() {
$('img[src*=astor]').offsetParent().css("background-color", "lightgrey");
});
</script>
В этой версии документа сначала с помощью CSS устанавливается значение свойства position элементов с атрибутом id равным row1 и row2. Далее в документе выбирается один из элементов img и с помощью метода offsetParent() находится ближайший позиционированный потомок выбранного элемента. После этого с помощью метода css() для свойства background-color выбранного элемента устанавливается значение lightgrey. Вид результирующей страницы в окне браузера представлен на рисунке:
Перемещение по дереву DOM в пределах одного иерархического уровня
Последняя разновидность перемещений по DOM-дереву, которую нам осталось рассмотреть, — это перемещение между узлами одного и того же уровня иерархии (между сестринскими узлами). Краткое описание предназначенных для этого методов jQuery приведено в таблице ниже:
Метод | Описание |
---|---|
next(), next(селектор) | Выбирает сестринские элементы, непосредственно следующие за каждым из элементов, содержащихся в объекте jQuery. Имеется дополнительная возможность фильтрации результатов с использованием селектора |
nextAll(), nextAll(селектор) | Выбирает все последующие сестринские элементы для каждого из элементов, содержащихся в объекте jQuery. Имеется дополнительная возможность фильтрации результатов с использованием селектора |
nextUntil(селектор), nextUntil(селектор, селектор), nextUntil(jQuery), nextUntil(jQuery, селектор), nextUntil(HTMLElement[]), nextUntil(HTMLElement[], селектор) | Выбирает для каждого элемента последующие сестринские элементы вплоть до элемента (но не включая его), соответствующего селектору или содержащегося в объекте jQuery или массиве HTMLElement[]. Имеется дополнительная возможность фильтрации результатов с использованием селектора |
prev(), prev(селектор) | Выбирает сестринские элементы, непосредственно предшествующие каждому из элементов, содержащихся в объекте jQuery. Имеется дополнительная возможность фильтрации результатов с использованием селектора |
prevAll(), prevAll(селектор) | Выбирает все предшествующие сестринские элементы для каждого из элементов, содержащихся в объекте jQuery. Имеется дополнительная возможность фильтрации результатов с использованием селектора, передаваемого методу в качестве второго аргумента |
prevUntil(селектор), prevUntil(селектор, селектор), prevUntil(jQuery), prevUntil(jQuery, селектор), prevUntil(HTMLElement[]), prevUntil(HTMLElement[], селектор) | Выбирает для каждого элемента предшествующие сестринские элементы вплоть до элемента (но не включая его), соответствующего селектору или содержащегося в объекте jQuery или массиве HTMLElement[]. Имеется дополнительная возможность фильтрации результатов с использованием селектора, передаваемого методу в качестве второго аргумента |
siblings(), siblings(селектор) | Выбирает все сестринские элементы для каждого из элементов, содержащихся в объекте jQuery. Имеется дополнительная возможность фильтрации результатов с использованием селектора |
Выбор всех сестринских элементов
Метод siblings() обеспечивает возможность выбора всех сестринских элементов для всех элементов, содержащихся в объекте jQuery. Пример использования этого метода приведен ниже:
$(function() {
$('img[src*=astor], img[src*=primula]')
.parent().siblings().css("border", "thick solid blue");
});
В этом примере мы сначала выбираем два элемента img, затем находим их родительские элементы с помощью метода parent(), после чего выбираем сестринские элементы последних с помощью метода siblings(). При этом выбираются как предшествующие, так и последующие сестринские элементы и для свойства border каждого из них устанавливается определенное значение с помощью метода css(). Вид результирующей страницы в окне браузера представлен на рисунке:
Обратите внимание: выбираются лишь сестринские элементы, но не сами элементы. Разумеется, эта ситуация изменится, если один из элементов, содержащихся в объекте jQuery, является сестринским по отношению к другому, как показано в примере ниже:
$(function() {
$('#row1 div.dcell').siblings().css("border", "thick solid blue");
});
В этом сценарии мы начинаем с выбора всех элементов div, являющихся дочерними по отношению к элементу rowl, а затем вызываем метод siblings(). Каждый из элементов в выбранном наборе является сестринским в отношении по крайней мере одного из других элементов, как показано на рисунке:
Выбор последующих и предшествующих сестринских элементов
Я не собираюсь подробно останавливаться на каждом из методов, предназначенных для выбора предшествующих и последующих сестринских элементов, поскольку все они работают аналогично любому другому методу, обеспечивающему перемещение между узлами DOM-дерева. Пример использования методов nextAll() и prevAll() приведен ниже:
$(function() {
$('img[src*=astor]').parent().nextAll().css("border", "thick solid blue");
$('img[src*=primula]').parent().prevAll().css("border", "thick double red");
});
В этом сценарии для родительского элемента изображения астры выбираются все последующие сестринские элементы, а для родительского элемента изображения примулы — все предыдущие сестринские элементы. Результат работы сценария представлен на рисунке: