Навигация по DOM
Выборку можно применить в качестве начальной точки для перемещения по DOM, по сути использовать одну выборку в качестве начальной точки для создания другой. В следующих разделах я опишу и покажу методы навигации jQuery. В главе 2 я рассказал о том, какие виды отношений могут существовать между элементами в документе.
Совет
Все методы, которые описаны в следующих разделах, возвращают объект
jQuery
. Этот объект содержит подходящие элементы, если таковые есть, и является пустым (то есть, свойствоlength
равно нулю), если таковых нет.
Перемещение вниз по дереву DOM
При переходе вниз по иерархии DOM выбираются дочерние элементы и элементы-потомки тех элементов, которые содержатся в объекте JQuery
. В таблице 6-8 описаны соответствующие методы JQuery
.
Таблица 6-8: Методы для перемещения вниз по иерархии DOM
Метод | Описание |
children() |
Выбирает дочерние элементы всех элементов в объекте jQuery |
children(selector) |
Выбирает все элементы, которые соответствуют селектору и являются дочерними элементами элементов объекта jQuery |
contents() |
Возвращает дочерние элементы и текстовое содержание всех элементов в объекте jQuery |
find() |
Выбирает потомков элемента в объекте jQuery |
find(selector) |
Выбирает все элементы, которые соответствуют селектору и являются потомками элементов объекта jQuery |
find(jQuery) find(HTMLElement) find(HTMLElement[]) |
Выбирает пересечение между дочерними элементами элементов объекта jQuery и объектом аргумента |
Метод children
выбирает только те элементы, которые являются непосредственными потомками каждого элемента в объекте jQuery
, с дополнительной фильтрацией при помощи селектора. Метод find
выбирает всех потомков, не только непосредственных. Метод contents
возвращает дочерние элементы и текстовое содержание. В листинге 6-11 показано, как используются методы children
и find
.
Листинг 6-11: Использование методовchildren
иfind
...
<script type="text/javascript">
$(document).ready(function () {
var childCount = $('div.drow').children().each(function (index, elem) {
console.log("Child: " + elem.tagName + " " + elem.className);
}).length;
console.log("There are " + childCount + " children");
var descCount = $('div.drow').find('img').each(function (index, elem) {
console.log("Descendant: " + elem.tagName + " " + elem.src);
}).length;
console.log("There are " + descCount + " img descendants");
});
</script>
...
В этом примере я использовал метод children
без селектора, а метод find
с селектором. Я вывел информацию о выбранных элементах, а также число выбранных элементов на консоль. На консоли виден следующий результат работы скрипта:
Child: DIV dcell
Child: DIV dcell
Child: DIV dcell
Child: DIV dcell
Child: DIV dcell
Child: DIV dcell
There are 6 children
Descendant: IMG http://www.jacquisflowershop.com/jquery/astor.png
Descendant: IMG http://www.jacquisflowershop.com/jquery/daffodil.png
Descendant: IMG http://www.jacquisflowershop.com/jquery/rose.png
Descendant: IMG http://www.jacquisflowershop.com/jquery/peony.png
Descendant: IMG http://www.jacquisflowershop.com/jquery/primula.png
Descendant: IMG http://www.jacquisflowershop.com/jquery/snowdrop.png
There are 6 img descendants
Одной из приятных особенностей использования методов children
и find
является то, что в выборке не будет дублированных элементов. В листинге 6-12 показан пример.
Листинг 6-12: Создание выборки с дублирующими потомками
...
<script type="text/javascript">
$(document).ready(function () {
$('div.drow').add('div.dcell').find('img').each(function (index, elem) {
console.log("Element: " + elem.tagName + " " + elem.src);
});
});
</script>
...
В этом примере я начал с создания объекта jQuery
, который содержит все элементы div
, являющиеся членами класса drow
, и все элементы div
, являющиеся членами класса dcell
. Главное, что стоит отметить, это то, что все члены класса dcell
содержатся среди членов класса drow
; это обозначает, что тут пересекаются наборы элементов-потомков и возникает возможность дублирования, когда я использую метод find
с селектором img
, поскольку элементы img
являются потомками обоих классов элементов div
. Но JQuery
приходит на помощь и гарантирует, что среди возвращенных элементов нет дубликатов, как видно по результату работы этого скрипта:
Element: IMG http://www.jacquisflowershop.com/jquery/astor.png
Element: IMG http://www.jacquisflowershop.com/jquery/daffodil.png
Element: IMG http://www.jacquisflowershop.com/jquery/rose.png
Element: IMG http://www.jacquisflowershop.com/jquery/peony.png
Element: IMG http://www.jacquisflowershop.com/jquery/primula.png
Element: IMG http://www.jacquisflowershop.com/jquery/snowdrop.png
Использование метода find для создания пересекающейся выборки
В метод find
в качестве параметров можно передать объект jQuery
, объект HTMLElement
или массив объектов HTMLElement
. Если сделать так, то будет выбрано пересечение между потомками исходного объекта jQuery
и элементами в объекте аргумента. В листинге 6-13 показан пример.
Листинг 6-13: Использование метода find
для создания пересекающейся выборки
<script type="text/javascript">
$(document).ready(function () {
var jq = $('label').filter('[for*=p]').not('[for=peony]');
$('div.drow').find(jq).css("border", "thick solid blue");
});
</script>
Как показано в этом скрипте, преимущество такого подхода заключается в том, что можно очень точно указать элементы, которые пересекаются с элементами-потомками. Я создал объект jQuery
, а потом сократил его, используя методы filter
и not
. Затем этот объект стал аргументом метода find
для другого объекта jQuery
, который содержит все элементы div
класса drow
. Итоговая выборка является пересекающейся выборкой между потомками элементов div.drow
и моим сокращенным набором элементов label
. Результат работы скрипта можно увидеть на рисунке 6-8.
Рисунок 6-8: Использование метода find
для создания пересекающейся выборки

Перемещение вверх по дереву DOM
При продвижении вверх по иерархии мы заинтересованы в родительских элементах и предках элементов, содержащихся в объекте jQuery
. В таблице 6-9 представлены методы, которые можно использовать для продвижения вверх по дереву DOM.
Таблица 6-9: Методы для продвижения вверх по дереву DOM
Метод | Описание |
closest(selector) closest(selector, context) |
Выбирает ближайшего предка для каждого элемента в объекте jQuery , который пересекается с указанным селектором. |
closest(jQuery) closest(HTMLElement) |
Выбирает ближайшего предка для каждого элемента в объекте jQuery , который пересекается с элементами, содержащимися в объекте аргумента. |
offsetParent() |
Находит ближайшего предка, значение CSS атрибута position которого равно fixed , absolute или relative . |
parent() parent(selector) |
Выбирает родительский элемент для каждого элемента в объекте jQuery , дополнительная фильтрация при помощи селектора |
parents() parents(selector) |
Выбирает предков для каждого элемента в объекте jQuery , дополнительная фильтрация при помощи селектора |
parentsUntil(selector) parentsUntil(selector, selector) |
Выбирает предков для каждого элемента в объекте jQuery , пока не найдется соответствие селектору. Результаты могут быть отфильтрованы с использованием второго селектора |
parentsUntil(HTMLElement) parentsUntil(HTMLElement, selector) parentsUntil(HTMLElement[]) parentsUntil(HTMLElement[], selector) |
Выбирает предков для каждого элемента в объекте jQuery , пока не встретится один из указанных элементов. Результаты могут быть отфильтрованы с использованием селектора |
Выбор родительских элементов
Метод parent
позволяет выбрать родительский элемент каждого из элементов в объекте jQuery
. Если добавляется селектор, то в результат будут включены только соответствующие этому селектору родительские элементы. В листинге 6-14 показано использование метода parent
.
Листинг 6-14: Использование метода parent
<script type="text/javascript">
$(document).ready(function () {
$('div.dcell').parent().each(function (index, elem) {
console.log("Element: " + elem.tagName + " " + elem.id);
});
$('div.dcell').parent('#row1').each(function (index, elem) {
console.log("Filtered Element: " + elem.tagName + " " + elem.id);
});
});
</script>
В этом скрипте я выбрал все элементы div
, которые являются членами класса dcell
, а затем вызвал метод parent
, чтобы выбрать родительские элементы. Также в этом примере я использовал метод parent
с селектором. Я использовал метод each
, чтобы вывести информацию о выбранных родительских элементах на консоль; результат такой:
Element: DIV row1
Element: DIV row2
Filtered Element: DIV row1
Выбор элементов-предков
Метод parents
(обратите внимание на последнюю букву s) позволяет сделать выборку всех предков элементов в объекте jQuery
, а не только непосредственных родительских элементов. Тут также можно указать селектор в качестве аргумента метода, чтобы отфильтровать результат. В листинге 6-15 показано использование метода parents
.
Листинг 6-15: Использование метода parents
<script type="text/javascript">
$(document).ready(function () {
$('img[src*=peony], img[src*=rose]').parents().each(function (index, elem) {
console.log("Element: " + elem.tagName + " " + elem.className + " " + elem.id);
});
});
</script>
В этом примере я выбрал два элемента img
и использовал метод parents
, чтобы выбрать их предков. Потом я вывел информацию о каждом предке на консоль; результат следующий:
Element: DIV dcell
Element: DIV drow row2
Element: DIV dcell
Element: DIV drow row1
Element: DIV dtable
Element: DIV oblock
Element: FORM
Element: BODY
Element: HTML
Одним из вариантов выбора предков является использование метода parentsUntil
. Каждый элемент в объекте jQuery
метод parentsUntil
обрабатывает вверх по дереву DOM, выбирая предков элементов, пока не встретится элемент, подходящий селектору. В листинге 6-16 представлен пример.
Листинг 6-16: Использование метода parentsUntil
<script type="text/javascript">
$(document).ready(function () {
$('img[src*=peony], img[src*=rose]').parentsUntil('form')
.each(function (index, elem) {
console.log("Element: " + elem.tagName + " " + elem.className + " " + elem.id);
});
});
</script>
В этом примере идет выборка предков каждого элемента до тех пор, пока не встретится элемент form
. Результат работы скрипта следующий:
Element: DIV dcell
Element: DIV drow row2
Element: DIV dcell
Element: DIV drow row1
Element: DIV dtable
Element: DIV oblock
Обратите внимание, что элементы, которые подходят селектору, исключаются из выбранных элементов-предков. Для данного примера это обозначает, что элемент form
будет исключен. Можно отфильтровать набор элементов-предков, назначив вторым аргументом селектор, как показано в листинге 6-17.
Листинг 6-17: Фильтрация набора элементов, выбранных при помощи метода parentsUntil
<script type="text/javascript">
$(document).ready(function () {
$('img[src*=peony], img[src*=rose]').parentsUntil('form', ':not(.dcell)')
.each(function (index, elem) {
console.log("Element: " + elem.tagName + " " + elem.className + " " + elem.id);
});
});
</script>
В этом примере я добавил селектор, который отфильтровал элементы, принадлежащие классу dcell
. Результат работы скрипта следующий:
Element: DIV drow row2
Element: DIV drow row1
Element: DIV dtable
Element: DIV oblock
Выбор первого подходящего элемента-предка
Метод closest
позволяет выбрать первого предка, который подходит селектору, для каждого элемента в объекте jQuery
. В листинге 6-18 показан пример.
Листинг 6-18: Использование метода closest
<script type="text/javascript">
$(document).ready(function () {
$('img').closest('.drow').each(function (index, elem) {
console.log("Element: " + elem.tagName + " " + elem.className
+ " " + elem.id);
});
var contextElem = document.getElementById("row1");
$('img').closest('.drow', contextElem).each(function (index, elem) {
console.log("Context Element: " + elem.tagName + " " + elem.className
+ " " + elem.id);
});
});
</script>
В этом примере я выбрал в документе элементы img
, а потом использовал метод closest
, чтобы найти ближайшего предка, который принадлежит к классу drow
.
Можно сузить диапазон выборки элементов-предков, указав объект HTMLElement
в качестве второго аргумента этого метода. Элементы-предки, которые не являются контекстными объектами или не являются потомками контекстного объекта, исключены из выборки. Результат работы скрипта такой:
Element: DIV drow row1
Element: DIV drow row2
Context Element: DIV drow row2
Когда вы назначаете объект jQuery
или один или несколько объектов HTMLElement
в качестве аргумента метода closest
, jQuery будет производить поиск, поднимаясь вверх по дереву от элемента-потомка, для каждого элемента в исходном объекте jQuery
, пока не найдет первый подходящий элемент. В листинге 6-19 представлен пример.
Листинг 6-19: Использование методасlosest
с объектомjQuery
<script type="text/javascript">
$(document).ready(function () {
var jq = $('#row1, #row2, form');
$('img[src*=rose]').closest(jq).each(function (index, elem) {
console.log("Context Element: " + elem.tagName + " " + elem.className + " " + elem.id);
});
});
</script>
В этом примере я выбрал один из элементов img
в документе, а затем использовал метод сlosest
, чтобы выбрать предков. В качестве аргумента методу сlosest
я назначил jQuery
объект, содержащий элемент form
и элементы с id
row1
и row2
. jQuery выберет любой из этих элементов, который является ближайшим предком элемента img
. Другими словами, он начнет работу с элемента-потомка, поднимаясь вверх по дереву, пока не встретит один из элементов, указанных в аргументе. Результат работы этого скрипта следующий:
Context Element: DIV drow row1
offsetParent
является вариацией метода closest
, и он находит первого предка, значение CSS атрибута position
которого равно relative
, absolute
или fixed
. Такой элемент называется позиционированный предок, и его нахождение может быть полезно при работе с анимацией (в главе 10 подробно рассказывается о поддержке анимации в jQuery). В листинге 6-20 показан пример использования этого метода.
Листинг 6-20: Использование метода offsetParent
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-1.7.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css" />
<style type="text/css">
#oblock { position: fixed; top: 120px; left: 50px; }
</style>
<script type="text/javascript">
$(document).ready(function () {
$('img[src*=astor]').offsetParent().css("background-color", "lightgrey");
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<form method="post">
<div id="oblock">
<div class="dtable">
<div id="row1" class="drow">
<div class="dcell">
<img src="astor.png" /><label for="astor">Astor:</label>
<input name="astor" value="0" required>
</div>
<div class="dcell">
<img src="daffodil.png" /><label for="daffodil">Daffodil:</label>
<input name="daffodil" value="0" required>
</div>
<div class="dcell">
<img src="rose.png" /><label for="rose">Rose:</label>
<input name="rose" value="0" required>
</div>
</div>
</div>
</div>
<div id="buttonDiv">
<button type="submit">Place Order</button></div>
</form>
</body>
</html>
В этой сокращенной версии примера документа я применяю CSS, чтобы установить значение для свойства position
для элемента с id
равном oblock
. В данном скрипте я использую jQuery, чтобы выбрать один из элементов img
, а потом вызываю метод offsetParent
, чтобы найти ближайший позиционированный элемент. Этот метод проходит вверх по дереву, пока не достигнет элемента с одним из требуемых значений. Я использую свойство css
, чтобы установить значение атрибуту background-color
для выбранных элементов, как видно на рисунке 6-9.
Рисунок 6-9: Нахождение ближайшего позиционированного предка

Перемещение по одному уровню дерева DOM
И последним способом перемещения по DOM является перемещение по элементам одного уровня. В таблице 6-10 представлены методы, которые используются в jQuery для этой цели.
Таблица 6-10: Методы для перемещения по одному уровню дерева DOM
Метод | Описание |
next() next(selector) |
Выбирает ближайший следующий сестринский элемент (сиблинг) для каждого элемента в объекте jQuery , дополнительная фильтрация возможна при помощи селектора |
nextAll() nextAll(selector) |
Выбирает всех следующих сиблингов для каждого элемента в объекте jQuery , дополнительная фильтрация возможна при помощи селектора |
nextUntil((selector) nextUntil(selector, selector) nextUntil(jQuery) nextUntil(jQuery, selector) nextUntil(HTMLElement[]) nextUntil(HTMLElement[], selector) |
Выбирает следующих сиблингов для каждого элемента вплоть до (и исключая его) элемента, который соответствует селектору или элементу в объекте jQuery или массиве HTMLElement . Дополнительная фильтрация возможна при помощи селектора в качестве второго аргумента метода |
prev() prev(selector) |
Выбирает ближайшего предыдущего сиблинга для каждого элемента в объекте jQuery , дополнительная фильтрация возможна при помощи селектора |
prevAll() prevAll(selector) |
Выбирает всех предыдущих сиблингов для каждого элемента в объекте jQuery , дополнительная фильтрация возможна при помощи селектора |
prevUntil(selector) prevUntil(selector, selector) prevUntil(jQuery) prevUntil(jQuery, selector) prevUntil(HTMLElement[]) prevUntil(HTMLElement[], selector) |
Выбирает предыдущих сиблингов для каждого элемента вплоть до (и исключая его) элемента, который соответствует селектору или элементу в объекте jQuery или массиве HTMLElement . Дополнительная фильтрация возможна при помощи селектора в качестве второго аргумента метода |
siblings() siblings(selector) |
Выбирает всех сиблингов для каждого элемента в объекте jQuery , дополнительная фильтрация возможна при помощи селектора |
Выбор всех сиблингов
Метод siblings
выбирает всех сиблингов всех элементов в объекте jQuery
. В листинге 6-21 показано, как используется этот метод. (Для этого листинга я вернулся к полному документу цветочного магазина, показанного в листинге 6-1).
Листинг 6-21: Использование метода siblings
<script type="text/javascript">
$(document).ready(function () {
$('img[src*=astor], img[src*=primula]')
.parent().siblings().css("border", "thick solid blue");
});
</script>
В этом примере я выбрал два элемента img
, вызвал метод parent
, чтобы выбрать их родительские элементы, а затем вызвал метод siblings
, чтобы выбрать их сиблингов. Были выбраны как предыдущие, так и следующие сиблинги, и я использовал метод css
, чтобы установить значение для свойства border
. Результат можно увидеть на рисунке 6-10. (Я использовал метод parent
, чтобы сделать эффект CSS свойства четче).
Рисунок 6-10: Выбор сиблингов

Обратите внимание, что выбраны только сиблинги, но не сами элементы. Конечно, все по-другому, если один элемент в объекте jQuery является сиблингом другого, как показано в листинге 6-22.
Листинг 6-22: Дублирование сиблингов
<script type="text/javascript">
$(document).ready(function () {
$('#row1 div.dcell').siblings().css("border", "thick solid blue");
});
</script>
В этом скрипте я начал с выборки всех элементов div
, которые являются дочерними элементами для row1
, и вызвал метод siblings
. Каждый из элементов в этой выборке является сиблингом как минимум для одного из других элементов, что можно увидеть на рисунке 6-11
Рисунок 6-11: Дублирование сиблингов

Выбор предыдущих и следующих сиблингов
Я не буду показывать на примере все методы для выбора предыдущих и следующих сиблингов, потому что они работают по тому же принципу, как и другие методы для навигации. В листинге 6-23 показано использование методов nextAll
и prevAll
.
Листинг 6-23: Использование методовnextAll
иprevAll
<script type="text/javascript">
$(document).ready(function () {
$('img[src*=astor]').parent().nextAll().css("border", "thick solid blue");
$('img[src*=primula]').parent().prevAll().css("border", "thick double red");
});
</script>
В этом скрипте выбираются следующие сиблинги для родительского элемента рисунка с астрой и предыдущие сиблинги для родительского элемента рисунка с примулой. Результат работы скрипта можно увидеть на рисунке 6-12.
Рисунок 6-12: Выбор предыдущих и следующих сиблингов
