Выбор родительских элементов с помощью CSS и JQuery
() translation by (you can also view the original English article)
Там были случаи, когда я хотел, чтобы я был в состоянии выбрать родительский элемент с помощью CSS-и я не одинок в этом вопросе. Тем не менее, не существует такого понятия, как Родитель селектор в CSS, так что это просто не представляется возможным до поры до времени.
В этом уроке мы будем ходить через несколько случаев, когда имеющих CSS селектор родительский может пригодиться, наряду с некоторыми возможных путей их устранения. Давайте начнем!
Подождите, Что такое родительский селектор?
CSS селекторы позволяют нам целевые элементы, двигаясь вниз и по всему дереву DOM, становится более конкретным, как мы делаем это. Вот пример такого рода выбора, которые можно найти в загрузчик это путешествия вниз по дереву DOM из элемента nav.navbar-dark
, ul
, li
, затем наконец a.nav-link
.
1 |
.navbar-dark .navbar-nav .nav-item .nav-link { |
2 |
|
3 |
}
|
Родитель селектор позволит нам путешествовать назад вверх по DOM, ориентированных на родительские элементы определенных вещей. Например, мы могли бы предназначаться родителя .nav-link
элементы с помощью:
1 |
.nav-link::parent { |
2 |
|
3 |
}
|
Примечание: этот пример чисто псевдокод, она не существует ни предложить наилучший синтаксис!
Случай 1: Стайлинг Наследие Содержание
Стайлинг наследство содержание, с датой разметкой и структурой, представляет собой классический вызов при разработке веб-сайта. Перед тем как HTML5, например, изображение, возможно, как правило, с добавленным в р
, div
, а иногда и с span
вместе с вложенной р
используется, чтобы обернуть подписи к изображению. Там не было никакого стандартного способа обернуть изображение и подпись. Позже, мы приняли figure
и figcaption
элементы, что делает наша структура документа более семантическим.



Мы хотим, чтобы изображения с содержанием унаследованной появляться, как описано выше. Но так как там может быть больше div
теги в нашем документе, те, которые не содержат изображения на всех, следующие объявления стилей было бы совершенно непрактичным.
1 |
.page-content div { |
2 |
padding: 15px; |
3 |
background-color: #f3f3f3; |
4 |
margin: 10px 0 20px; |
5 |
}
|
6 |
.page-content div img { |
7 |
marging: 0 0 10px; |
8 |
}
|
9 |
.page-content div .img-caption { |
10 |
color: #999; |
11 |
font-size: 12px; |
12 |
text-align: center; |
13 |
Wisplay: block; |
14 |
}
|
Было бы применить цвет фона, отступы и поля для всех элементов div в содержании. На самом деле мы хотим применить эти стили исключительно div
элементы, которые обертка изображения и подписи к изображению.
Случай 2: Поддержание пропорции видео
Другой пример выглядит на поддержание встроенного видео (ссылка с Youtube или Vimeo) соотношение, а также сделать видео жидкость. В эти дни, во многом благодаря исследовательской работы Дэйв Рупертом и приятелями, это широко признано, что лучшим подходом является применение padding-top
или padding-bottom
к родительскому элементу.



В реальном мире, однако, мы можем бы не знать, какой элемент содержит видео. Мы можем найти некоторые встроенные видео, завернутые в div
или p
без имени идентифицируемого класса, что делает его сложно выбрать подходящий элемент, на котором будет применить стили.
Поэтому, объявляя стили следующим образом снова нецелесообразно, так как это будет влиять на все дивы в пределах .page-content
в том числе и те, которые не содержат встроенного видео.
1 |
.page-content { |
2 |
width: 560px; |
3 |
margin-right: auto; |
4 |
margin-left: auto; |
5 |
margin-top: 30px; |
6 |
}
|
7 |
.page-content div { |
8 |
position: relative; |
9 |
padding-bottom: 56.25%; |
10 |
}
|
11 |
.page-content div iframe { |
12 |
position: absolute; |
13 |
top: 0; |
14 |
width: 100%; |
15 |
height: 100%; |
16 |
}
|
Как было бы замечательно, чтобы непосредственно выбрать родительский элемент данного видео!
Случай 3: В ответ на форму ввода
В этом примере у нас есть форма с несколькими входами. Когда мы сосредотачиваемся на одном из входов, она дается более видную цвет границы, выделяя позицию пользователя внутри формы.
Иногда вы также можете столкнуться с ситуацией, когда подсвечивается не только цвет границы, но элемент упаковки вход, что делает ввод еще более заметным:



Родительский элемент может быть div
или р
. Итак, как же мы можем правильно выбрать родительский элемент на основе определенных состояний его потомков?
Возможные обходные
Как мы уже рассмотрели, нет такого понятия, как родительский селектор, так что выбор одного из родителей не представляется возможным. Мы могли бы попытаться обойти эту проблему, с помощью полностью пересмотреть конструкцию так, чтобы выбирая родителя избегается. Но если это не представляется возможным, то здесь некоторые потенциальные подходы.
Использование CSS :has()
селектор
:has
селектор официально называется реляционной псевдо-класса. Он соответствует элементы на основе их потомков, которые определены между круглыми скобками.
В следующем примере, он применяет background-color
к любой div
, содержащий заголовок изображения. Этот на первый взгляд обращается случай 1.
1 |
.page-content div:has( .img-caption ) { |
2 |
padding: 15px; |
3 |
background-color: #ccc; |
4 |
}
|
Или, если мы хотим, чтобы быть более точным, мы можем переписать его, чтобы соответствовать любому div
тег с .img-caption
как прямой потомок.
1 |
.page-content div:has( > .img-caption ) { |
2 |
padding: 15px; |
3 |
background-color: #ccc; |
4 |
}
|
Этот селектор разработан для уровня CSS Selector 4 хотя никакие браузеры не реализовать его пока нет. Нам придется подождать немного дольше, прежде чем этот селектор приходит к свету. До тех пор, пока взгляните на следующий курс видео под названием CSS будущего, чтобы узнать, как работает селектор:
Использование Parent селектор JQuery
Ни одно решение CSS не может исправить наши вопросы здесь, так что давайте посмотрим, что JavaScript может сделать для нас вместо этого. В этом примере мы будем использовать JQuery для его надежные API, удобство и совместимость браузера. На момент написания JQuery предоставляет три метода для выбора родительских элементов.
parent();
этот метод выбирает непосредственный вышестоящий целевого элемента. Мы можем использовать этот метод для решения всех наших случаев использования упомянутых ранее в учебнике.



Например, мы можем использовать parent()
, чтобы добавить специальный класс к упаковочному элементу изображений в пределах содержания.
1 |
$( ".img-caption" ) |
2 |
.parent() |
3 |
.addClass( "has-img-caption" ); |
Приведенный выше код будет выбрать непосредственный элемент оберточной изображения, независимо от типа элемента, добавив класс has-image-caption
, чтобы дать нам больше контроля над выбора элементов и стилей, следующим образом.



parents()
обратите внимание на форму множественного числа этого метода. Этот метод позволяет выбрать родительские элементы из немедленного, вплоть до корня документа, если селектор не указан в качестве аргумента.
1 |
$( ".img-caption" ) |
2 |
.parents() |
3 |
.addClass( "has-img-caption" ); |
Учитывая приведенный выше пример, метод parents()
выбирает весь путь от div
тега, который сразу оборачивает изображение, следующий div
, и, наконец, html
, добавив класс has-image-caption
ко всем элементам.



Такие излишним является излишним. Единственный элемент, который, скорее всего, нужно иметь добавил класс, в данном случае, является непосредственным элементом div
. Поэтому мы передаем его в аргументе метода.
1 |
$( ".img-caption" ) |
2 |
.parents( "div" ) |
3 |
.addClass( "has-img-caption" ); |
Здесь метод parents()
будут проходить через предка дерева изображения, выбрав любую div
нашел и придавая ему класс has-image-caption
.
Если это все-таки властный, вы можете сузить выбор вниз к одному элементу, указав индекс. В следующем примере мы применим класс только к первому div
.
1 |
var $parents = $( ".caption" ).parents( "div" ); |
2 |
$parents[0].addClass( "has-img-caption" ); // select the first div add add the class. |
parentsUntil();
этот метод выбирает родительские элементы вплоть до, но не включая элемент, указанный в скобках.
1 |
$( ".caption" ) |
2 |
.parentsUntil( ".page-content" ) |
3 |
.addClass( "has-img-caption" ); |
Учитывая приведенный выше код, он будет применять класс has-img-caption
для всех родительских элементов, кроме элемента с .page-content
.



В некоторых случаях, когда вы Gazillion вложенные элементы, используя метод parentsUntil()
является предпочтительным. Это сравнительно быстрее, чем parents()
метод, как он избегает с помощью селектора двигатель jQuery (Sizzle), чтобы путешествовать по всему DOM дерева до корня документа.
Подведению
Действительно ли мы, скорее всего, чтобы иметь CSS Parent Selector в какой-то момент в будущем?
Возможно нет. Вид родительского селектора, который мы обсуждали выше было предложено много раз, но он никогда не проходил W3C стадии проекта по нескольким причинам. Эти причины в основном сосредоточены на производительности браузера, благодаря тому, как браузеры оценки и визуализации страниц. Самая близкая вещь we'all иметь в будущем является реляционная селектор, :has()
.
Тем не менее, так как :has()
еще не применяется, JavaScript и JQuery в настоящее время наиболее надежным подходом. Имейте в виду, что DOM Traversal является дорогостоящей операцией, которая может сильно повлиять на производительность рендеринга вашего сайта. Избегайте использования parents()
или parentsUntil()
с другими тяжелыми операциями, как animate()
, fadeIn()
или fadeOut()
.
А еще лучше, изучить структуру HTML, когда это возможно, чтобы увидеть, если выбрать родительский элемент можно полностью избежать!