Nano Hash - криптовалюты, майнинг, программирование

Почему CSS моего веб-компонента не отображается? Я не использую shadowDOM

У меня есть компонент Native V1, который не использует shadowDOM, поэтому я помещаю свой CSS в файл <head>. Но когда кто-то другой использует мой компонент, мой CSS больше не работает.

Это происходит только в том случае, если их компонент использует shadowDOM.

Пример кода для моего компонента:

class MyEl extends HTMLElement {
  constructor() {
    super();
  }

  connectedCallback() {
    this.innerHTML = `<div class="spaced"><button class="happy-btn">I'm Happy</button></div>
    <div class="spaced"><button class="sad-btn">I'm Sad</button></div>`;
  }
}

// Define our web component
customElements.define('my-el', MyEl);
button {
  padding: 8px 20px;
}

.happy-btn {
  background-color: pink;
}

.sad-btn {
  background-color: #007;
  color: white;
}
<my-el></my-el>

Мой CSS загружается в тег <head>, так как я не использую shadowDOM. Но как только внешний элемент включает меня в свой shadowDOM, все разваливается.


Ответы:


1

Если вы создаете компонент, который НЕ использует ShadowDOM, вам может понадобиться добавить свой CSS в shadowRoot. Если кто-то поместит ваш компонент в свой shadowDOM, вы должны добавить свой CSS в его shadowRoot. Вы можете сделать это с помощью следующего кода:

const myStyle = document.createElement('style');
myStyle.setAttribute('component', 'my-el');
myStyle.textContent = `    button {
  padding: 8px 20px;
}
.happy-btn {
  background-color: pink;
}

.sad-btn {
  background-color: #007;
  color: white;
}`;

function addCss(el, selector, styleEl) {
  // Check to see if we have been placed into a shadow root.
  // If we have then add our CSS into that shadow root.
  let doc;
  try {
    doc = el.getRootNode();
    if (doc === document) {
      doc = document.head;
    }
  }
  catch(_ex) { doc = document.head; } // Shadow DOM isn't supported.

  if (!doc.querySelector(selector)) {
    doc.appendChild(styleEl.cloneNode(true));
  }
}

class MyEl extends HTMLElement {
  constructor() {
    super();
    addCss(this, 'style[component="my-el"]', myStyle);
  }
  connectedCallback() {
    this.innerHTML = `<div class="spaced"><button class="happy-btn">I'm Happy</button></div>
    <div class="spaced"><button class="sad-btn">I'm Sad</button></div>`;
  }
}
customElements.define('my-el', MyEl);

class TheirEl extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode:'open'});
    this.shadowRoot.innerHTML = `<hr/><my-el></my-el><hr/><my-el></my-el><hr/>`;
  }
}
customElements.define('their-el', TheirEl);
<their-el></their-el>

Функция addCss поместит ваш CSS в правильный shadowRoot или в document.head, если тени нет.

Вы должны вызвать addCss в своем конструкторе, чтобы разместить CSS в правильном месте. Эта процедура также гарантирует, что вы не добавите его дважды, если у вас есть уникальный селектор для идентификации вашего тега <style>.

В моем вы видите, что тег <style> добавляет атрибут с именем component со значением имени компонента. В моем случае component="my-el".

Затем я использую селектор 'style[component="my-el"]', чтобы увидеть, находится ли этот тег уже в shadowRoot, или document.head, если теневого корня нет, и добавляю стили, только если он еще не существует.

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

Примечание

Если вы используете теневой DOM, эта проблема исчезнет, ​​так как вам нужно поместить свой CSS в свой собственный shadowRoot.

22.02.2018
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..