Статьи

Комплексный взгляд на обход JQuery DOM

Отдельные элементы кода в больничных капельницах. Метафора для обхода DOM.

Обход DOM означает, что как только вы выбрали элемент или элементы на веб-странице, вы можете перемещаться по элементам страницы относительно вашего первоначального выбора. Во время этого процесса вы можете либо заменить исходный выбор новым, либо добавить и вычесть из него элементы.

В этой статье мы рассмотрим доступные методы обхода JQuery DOM и увидим, как библиотека предоставляет нам множество способов легко выбирать элементы на основе их отношений с другими элементами на странице.

Фильтрующие элементы

Давайте начнем с рассмотрения того, как отфильтровать выборку до чего-то более конкретного. Вы можете фильтровать элементы, основываясь на множестве условий, таких как их положение относительно других элементов и наличие у них определенного класса. В большинстве случаев у вас будет меньше элементов, чем вы начали.

Вот список различных методов фильтрации:

  • eq — этот метод сокращает набор соответствующих элементов до того, который находится по указанному вами индексу. Индексация начинается с нуля. Поэтому, чтобы выбрать первый элемент, вам нужно будет использовать $("selector").eq(0) . Начиная с версии 1.4, вы можете указать отрицательное целое число, чтобы начать считать элементы с конца, а не с начала.

  • first and lastfirst метод вернет только первый элемент из набора сопоставленных элементов, а 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() есть два существенных различия. Пока parent parents() начинает обход с родительского элемента, 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 как можно лучше!