При вставке элемента DOM из JavaScript стили CSS не отображаются

Я хочу отобразить журнал с заголовком и содержимым.

С помощью следующего кода элементы li вставляются в DOM с правильным className, но стили не отображаются.

Это внутри компонента Angular, который, я думаю, может быть причиной ошибки. Это просто новое приложение с html: <app-example></app-example>

Примечание: если я вставляю элемент вручную в html, он отображается правильно. Единственное отличие, которое я заметил, это то, что элементы li, вставленные из javascript, не имеют _ngcontent-cxr-c40.

HTML:

<ul class = "d-flex f-column log-list" id = "log-list">
        <li id = "log-item" class = "log-message">
          <span class = "log-message-title">TEST</span>
        </li>
</ul>

Это функция для добавления элемента в журнал:

  private addLogElement(title: string, message: string): void {
    const newNode = document.createElement('li');
    newNode.className = 'log-message';
    const newNodeTitle = document.createElement('span');
    newNodeTitle.className = 'log-message-title';

    const headerText = document.createTextNode(title);

    newNodeTitle.appendChild(headerText);
    newNode.appendChild(newNodeTitle);

    const parentDiv = document.getElementById('log-list');
    const childDiv = document.getElementById('log-item');
    parentDiv.insertBefore(newNode, childDiv);
  }

Ваш код должен работать, но это не "угловой способ". Используйте массив и *ngFor для этого массива:angular.io/guide/structural-directives, вам нужно только добавить элемент в массив

Eliseo 10.12.2020 17:06

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

isherwood 10.12.2020 17:10

Вероятно, есть некоторая польза от использования renderer2 при манипулировании домом, но он должен работать только с JS. Посетите digitalocean.com/community/tutorials/angular-using-renderer2 для получения дополнительной информации.

iamaword 10.12.2020 17:14
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
210
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Добавьте это в свой css/scss
Я добавил примеры стилей

:host ::ng-deep .log-message{
    color: red;
}
:host ::ng-deep .log-message-title{
    background-color: #eeee33
}
Ответ принят как подходящий

Вы должны использовать Renderer2 API для таких манипуляций с DOM.

В классе Component в конструкторе введите его так: -

constructor(public renderer: Renderer2) {}

Затем измените свой метод на: -

private addLogElement(title: string, message: string): void {
    const newNode = this.renderer.createElement('li');
    this.renderer.addClass(newNode, 'log-message');
    const newNodeTitle = this.renderer.createElement('span');
    this.renderer.addClass(newNodeTitle, 'log-message-title');
    const headerText = this.renderer.createText(title);
    this.renderer.appendChild(newNodeTitle, headerText);
    this.renderer.appendChild(newNode, newNodeTitle);

    const parentDiv = this.renderer.selectRootElement(document.getElementById('log-list'), true);
    const childDiv = this.renderer.selectRootElement(document.getElementById('log-item'), true);
    this.renderer.insertBefore(parentDiv, newNode, childDiv);
  }

Есть и другие причины, по которым вам следует использовать Renderer2 вместо нативных манипуляций с DOM.

Вы можете обратиться к этим причинам здесь: - https://medium.com/dev-genius/dont-use-native-dom-manipulations-in-angular-6c8db13f463f

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