У меня есть элемент, который я объявил как теневой дом, но стиль влияет на другие элементы

Код

<html>

<head>

</head>

<script src="https://cdnjs.cloudflare.com/ajax/libs/document-register- 
element/1.7.2/document-register-element.js"></script>
<div id = "1">
<style>
div {
    height: 30px;
    width: 30px;
    background-color: brown;
}
</style>
 </div>

 <script>
  document.getElementById('1').attachShadow({mode: "open"})
</script>
<div id = "2"></div>
<div id = "3"></div>
</body>

</html>

а ссылка на jsfiddle - https://jsfiddle.net/o5r229hf/

Я объявил div id 1 как shadow dom, но div id 2 и 3 получают стиль. Может ли быть что-то с порядком, в котором я написал элементы?

3 ответа

Вы создаете <style> пометить как ребенка <div id="1"> а не как дитя теневого DOM. Итак <style> существует вне тени, которую вы создали.

CSS должен существовать внутри shadowRoot, чтобы влиять на элементы в этом shadowRoot.

Любой CSS вне shadowRoot не должен влиять на элементы внутри shadowRoot. Одно незначительное исключение при использовании слотов.

Если ваш код ограничен тем, что вы показываете выше, вам нужно переместить CSS в shadowRoot, выполнив что-то вроде этого:

var el = document.getElementById('1');

var s = el.attachShadow({mode: "open"});

while(el.firstElementChild) {
  s.append(el.firstElementChild);
}
div {
  background-color: #F00;
  outline: 1px solid black;
  height: 80px;
  width: 80px;
}
<div id = "1">
  <style>
  div {
    height: 30px;
    width: 30px;
    background-color: brown;
  }
  </style>
  <div>I1</div>
</div>
<div id="2">
  <div>I2</div>
</div>
<div id="3">
  <div>I3</div>
</div>

Это копирует детей <div id="1"> в shadowRoot, который вы создали.

Это перемещает <style> тег внутри, который делает это влияет только на <div> и нет других.

Если ваш код не ограничен чем-то таким, как у вас выше, просто создайте CSS как дочерний элемент shadowRoot.

ОБНОВИТЬ:

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

Используя теневой DOM, вы можете нацелить родительский элемент в CSS с помощью :host:

<div id="1">
<style>
:host {
    height: 30px;
    width: 30px;
    background-color: brown;
}
</style>
</div>

Тем не менее, теневой DOM еще не обрабатывается должным образом, даже в самых последних браузерах.

Источник: https://developer.mozilla.org/fr/docs/Web/CSS/:host

1-е решение: шаблонные литералы

Определите <style> Элемент прямо в тени Дом:

document.getElementById('1').attachShadow({mode: "open"}).innerHTML = `<style>
:host {
    height: 30px;
    width: 30px;
    background-color: brown;
}
</style>
<slot></slot>`
<div id="1">D1</div>
<div id="2">D2</div>
<div id="3">D3</div>

2-е решение: HTML-шаблон

Определите все содержимое вашего теневого дома в <template> тег, а затем вставьте его в теневой дом.

var tpl = document.querySelector('template')
document.getElementById('1').attachShadow({mode: "open"}).appendChild(tpl.content)
<template>
  <style>
    :host {
      height: 30px;
      width: 30px;
      background-color: brown;
    }
  </style>
  D1
</template>

<div id="1"></div>
<div id="2">D2</div>
<div id="3">D3</div>

Другие вопросы по тегам