Обход DOM означает, что как только вы выбрали элемент или элементы на веб-странице, вы можете перемещаться по элементам страницы относительно вашего первоначального выбора. Во время этого процесса вы можете либо заменить исходный выбор новым, либо добавить и вычесть из него элементы.
В этой статье мы рассмотрим доступные методы обхода JQuery DOM и увидим, как библиотека предоставляет нам множество способов легко выбирать элементы на основе их отношений с другими элементами на странице.
Фильтрующие элементы
Давайте начнем с рассмотрения того, как отфильтровать выборку до чего-то более конкретного. Вы можете фильтровать элементы, основываясь на множестве условий, таких как их положение относительно других элементов и наличие у них определенного класса. В большинстве случаев у вас будет меньше элементов, чем вы начали.
Вот список различных методов фильтрации:
-
eq — этот метод сокращает набор соответствующих элементов до того, который находится по указанному вами индексу. Индексация начинается с нуля. Поэтому, чтобы выбрать первый элемент, вам нужно будет использовать
$("selector").eq(0)
. Начиная с версии 1.4, вы можете указать отрицательное целое число, чтобы начать считать элементы с конца, а не с начала. -
first and last —
first
метод вернет только первый элемент из набора сопоставленных элементов, аlast
вернет последний элемент из набора сопоставленных элементов. Ни один из этих методов не принимает никаких аргументов. -
slice — если вы ищете все элементы в наборе, чей индекс находится в заданном диапазоне, вы можете использовать
slice()
. Этот метод принимает два аргумента. Первый указывает начальный индекс, с которого метод должен начать нарезку, а второй аргумент указывает индекс, на котором выбор должен закончиться. Второй аргумент является необязательным и, если он опущен, приводит к выбору всех элементов, индекс которых больше или равенstart
. -
фильтр — этот метод уменьшит ваш набор элементов до тех, которые либо соответствуют селектору, либо соответствуют критериям, установленным вами в функции, которая передается этому методу. Вот один пример этого метода с селекторами:
$("li").filter(":even").css( "font-weight", "bold" );
Вы также можете выбрать те же элементы, используя функцию:
$("li") .filter(function( index ) { return index % 2 === 0; }) .css( "font-weight", "bold" );
Вы также можете использовать функцию для выполнения более сложных выборов, таких как:
.filter(function( index ) { return $( "span", this ).length >= 2; })
Это будет иметь только выбранные элементы, которые имеют как минимум два
span
. -
map — вы можете использовать этот метод для передачи каждого элемента в текущем выделении через функцию, в конечном итоге создав новый объект jQuery, содержащий возвращаемые значения. Возвращенный объект jQuery сам содержит массив, и вы можете использовать для
get
методget
для работы с базовым массивом.
Обход DOM
Рассмотрим сценарий, в котором вы знаете селектор, который вы можете использовать для доступа к различным элементам, но вам нужно работать с родителями всех этих элементов. Кроме того, у родителей нет определенного класса или тега, который является общим для всех них. Единственное, что у них общего, — это то, что все они являются родителями элементов, к которым у вас есть доступ. Я сталкивался с подобной ситуацией более чем несколько раз.
В таких случаях jQuery предоставляет множество полезных методов для доступа к родителям, детям или братьям и сестрам. Давайте рассмотрим их все по одному:
-
children — этот метод позволяет нам получить дочерние элементы каждого элемента в нашем наборе элементов. Эти дети могут быть отфильтрованы по выбору.
-
find — Этот метод получает все потомки каждого элемента в вашем наборе соответствующих элементов, отфильтрованные селектором или элементом. В этом случае аргумент селектора, передаваемый функции
find()
, не является обязательным. Если вы хотите получить всех потомков, вы можете передать универсальный селектор ('*'
) в качестве аргумента этому методу.Как вы можете видеть в демонстрации,
children()
только подчеркивает прямых потомков наших абзацев, ноfind()
добавляет фон всем своим потомкам с соответствующим селектором. -
parent — этот метод получит родителя каждого элемента в текущем наборе. Родители могут быть дополнительно отфильтрованы с помощью селектора.
-
родители — Этот метод получит всех предков для каждого элемента в вашем наборе. Он также принимает необязательный аргумент селектора для фильтрации предков. Разница между
parent()
иparent()
заключается в том, что предыдущий проходит только один уровень вверх в дереве DOM, в то время какparents()
проходит до корня документа. -
closest — этот метод получит первый элемент, соответствующий заданному селектору, протестировав сам элемент и затем перейдя в дерево DOM. Между
parents()
иclosest()
есть два существенных различия. Пока parentparents()
начинает обход с родительского элемента,closest()
начинает его с самого элемента. Другое отличие состоит в том, чтоclosest()
будет проходить только по дереву DOM, пока не найдет совпадение, в то время какparents()
будет двигаться вверх, пока не достигнет корневого элемента документа.Рассмотрим эти две строки кода, взятые из следующей демонстрации:
$("i").closest("span").css("background", "yellow"); $("b").parent().css("color","blue");
Теперь обратите внимание, что у слова «курсив» в последнем абзаце нет предка с
<span>
. Поэтому его фон не изменился.Аналогично, вторая строка изменила цвет тегов
<span>
заключающих наши жирные слова, в синий. Теперь в последнем случае весь абзац был родителем<b>
и поэтому он стал синим. -
siblings — этот метод получает братьев и сестер каждого элемента в наборе соответствующих элементов. При желании вы можете указать селектор в качестве аргумента, чтобы получить только братьев и сестер с соответствующим селектором.
-
prev — Этот метод получит непосредственно предшествующего брата каждого элемента в нашем наборе. Если вы указали селектор, метод выберет элемент, только если он соответствует этому селектору.
-
prevAll — Этот метод получит все предшествующие элементы каждого элемента в нашем наборе. Как и другие методы, вы можете предоставить селектор для фильтрации возвращаемых элементов.
-
next — Этот метод получит только ближайшего родственника соответствующих элементов. Если указан селектор, он получит брата, только если он совпадает.
-
nextAll — Этот метод получит всех братьев и сестер, которые являются наследниками элементов в нашем наборе. Брат или сестра могут быть отфильтрованы при помощи селектора.
Рассмотрим эти две строки кода из демонстрации:
$("selector").next(".nextall").css("color","orange"); $("selector").nextAll(".nextall").css("color","red");
Вы увидите, что ни один из элементов в списке не имеет оранжевого цвета. Это потому, что у следующего ближайшего брата нашего ссылочного элемента нет класса
nextall
.Я хотел бы еще раз упомянуть, что когда вы предоставляете селектор для
next()
иprev()
, они не будут искать всех следующих и предыдущих братьев и сестер, чтобы найти первый, который соответствует данному селектору. Они будут просто смотреть на непосредственно предшествующих и последующих братьев и сестер, и если у этих братьев и сестер нет соответствующего селектора, будет возвращен пустой объект jQuery.
Дополнительные методы, связанные с обходом DOM
При обходе DOM вы можете столкнуться с ситуациями, когда вам нужно добавить больше элементов в ваш выбор, которые не связаны с вашим исходным набором, или вам нужно вернуться к предыдущему набору элементов. JQuery предоставляет несколько функций, которые вы можете использовать для выполнения всех этих задач.
-
add — Этот метод создаст новый объект jQuery, который будет содержать наши новые элементы, добавленные в список существующих. Помните, что нет никакой гарантии, что новые элементы будут добавлены в существующую коллекцию в том порядке, в котором они были переданы в метод
add
. -
addBack — jQuery поддерживает внутренний стек, который используется для отслеживания изменений в вашем наборе элементов. Вызов любого из методов обхода помещает новый набор элементов в этот стек. Если вы хотите работать как с предыдущим, так и с новым набором элементов, вы можете использовать метод
addBack
.Для первого случая в разделе
addBack
мы начинаем с выбора абзаца, а затем вызываемchildren()
. Во втором случае после вызоваchildren()
мы также вызываемaddBack()
. ВызовaddBack()
добавляет второй абзац к нашему выделению, и затем мы применяем к нему красную рамку. -
end — Этот метод завершит самую последнюю операцию фильтрации и вернет ваш набор элементов в предыдущее состояние. Это может быть полезно в ситуациях, когда вы хотите манипулировать некоторыми элементами, связанными с вашим текущим набором элементов, вернуться к исходному набору и затем манипулировать другим набором элементов.
В демонстрации ниже я начинаю с использования
.find("b")
чтобы выбрать все теги<b>
а затем, как только я изменил их цвет на зеленый, я вызываю.end()
. Этот вызов возвращает нас к нашему предыдущему выбору, где я снова выбираю все теги<i>
. -
содержимое — если вы хотите получить все дочерние элементы, включая узлы текста и комментариев всех элементов в вашем наборе, вы можете использовать метод
contents
. Вы также можете использовать этот метод для получения содержимого<iframe>
если<iframe>
находится в том же домене, что и ваша веб-страница. -
not — Если у вас большой набор элементов и вы хотите только подмножество этих элементов, которые не соответствуют заданному селектору, вы можете использовать
not()
. Начиная с версии 1.4, метод может также принимать функцию в качестве аргумента для проверки каждого элемента на соответствие определенным условиям. Любой элемент, соответствующий этим условиям, будет исключен из отфильтрованного набора. В следующей демонстрации я добавил границу для всех элементов, которые не имеют.not(".not-selected")
класс, используя.not(".not-selected")
. Аналогично, в следующем наборе элементов div я также установил цвет всех элементов, высота которых не превышает 120 пикселей, на фиолетовый.
Вывод
Все эти методы в jQuery предоставляют нам простой способ перехода от одного набора элементов к другому. Поскольку некоторые из этих методов очень похожи друг на друга, я рекомендую вам обратить на них особое внимание. Зная разницу между parents()
и closest()
или next("selector")
и nextAll("selector").eq(0)
вероятно, может сэкономить вам несколько часов неприятностей в определенных ситуациях.
Надеюсь, вам понравилась эта статья. Если у вас есть какие-либо советы, которыми вы хотели бы поделиться с другими читателями, пожалуйста, прокомментируйте ниже!
Эта статья была рецензирована Джоан Инь и Крисом Перри . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!