Используйте селекторы CSS, такие как: first-child внутри shadow dom

Есть ли способ использовать селекторы CSS, такие как: first-child,: not (: last-child) внутри теневого дома?

Пример такой

CustomElement.html

<div id="parent-div>
 <slot></slot>
</div>

App.html

<div>
 <custom-element>
   <div class="heading">Main Heading</div>
   <div class="item">item 1</div>
   <div class="item">item 1</div>
   <div class="item">item 1</div>
   <div class="heading">Second Heading</div>
   <div class="item">item 1</div>
   <div class="item">item 1</div>
   <div class="item">item 1</div>
 </custom-element>
</div>

я хочу найти первый элемент .heading и добавить к нему собственные стили. Поскольку <div class=heading"> на самом деле является компонентом, я не могу добавить к нему собственный стиль, думая только как первый заголовок.

P.S.:- Я использую angular-elements, если поможет


person Kavinda Jayakody    schedule 15.04.2020    source источник


Ответы (2)


Тот же ответ, что я вчера дал в вашем вопросе

Размещенный контент не перемещается в shadowDOM,

он остается (невидимым) в lightDOM

и ОТРАЖАЕТСЯ в shadowDOM <SLOT>

Таким образом, оформление содержимого SLOTTED выполняется в области CSS, где находится <custom-element>.

или с ::slotted( x )

Из документов:

:: slotted может принимать только составной селектор (в скобках). Причина этого ограничения состоит в том, чтобы сделать селектор более удобным с точки зрения производительности.

Итак, с вашей структурой вы можете:

 ::slotted(.heading) { }
or
 ::slotted(:first-child) { }

но нет:

 ::slotted(.heading:first-child)

Потому что это сложный селектор, а не (простой) составной селектор

Таким образом, ваши заголовки могут быть стилизованы в глобальном CSS, и они будут ОТРАЖАТЬ на размещенный контент:

my-element div.heading{
  background:blue;
  color:white;
}

Если вы хотите инкапсулировать этот стиль, вам нужно обернуть все (другой) компонент

Вы можете настроить таргетинг на весь безымянный рекламный контент с помощью:

    ::slotted(:not([slot])){
      font-weight:bold;
    }

Вот еще один JSFiddle, чтобы поиграть со стилем с прорезями:

https://jsfiddle.net/CustomElementsExamples/whtjen3k/

person Danny '365CSI' Engelman    schedule 16.04.2020

Я нашел способ обойти это способом JS.

Для каждого слота у нас есть обработчик событий (slotchange). Используя это, мы можем получать событие DOM для слота при каждом изменении слота. Как это (HTML)

<custom-element (slotchange)="onSlotChanged($event)"></custom-element>

JS

onSlotChanged($event) {
 console.log($event) // Go and research yourself about this event, you'll find many things usefull.
 $event.target.assignedNodes() // This will give you the array of every elements, that are in side of the shadow dom
 // Example usage, adding the margin-bottom to only first time (css :firsh-child)
 $event.target.assignedNodes()[0].shadowRoot.getElementById('some-id').style.marginBottom = '10px'
}

Если вам нужно только добавить свойство к элементу, вам не нужно запрашивать shadowDom, например, «node.shadowRoot». Но если вы хотите получить доступ к элементу внутри shadowRoot этого элемента, вы должны использовать это

person Kavinda Jayakody    schedule 28.04.2020