Почему стили невидимы, а теги стилей не добавляются повторно после использования insertRule из CSSOM

Если я добавил стили с CSSOM, используя insertRule Я заметил две вещи.

Добавленные стили не отображаются в html при просмотре в Firebug.

Добавленные стили не работают, если тег стиля добавляется (например, перемещается из головы в тело) к другому элементу (происходит в Firefox и Chrome).

Если стили добавляются после добавления тега, они работают. Они все еще не показывают в Firebug. При добавлении лист должен быть переназначен (перезаписан?), Что делает его еще более странным.

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

Для стилей, не работающих после добавления, мне интересно, является ли это стандартом, потому что это происходит в Firefox и Chrome. Глядя на стандарты, я ничего не видел по этому поводу. Если я просто не понимаю их.

var style = document.createElement('style'),
    sheet = style.sheet;
document.head.appendChild(style);
//When line 6 is un-commented the styles work
//if line 8 is also commented out.
//document.querySelector('.container').appendChild(style);
//Get the sheet when line 6 is un-commented
sheet = style.sheet
sheet.insertRule('.test{color: red}');
document.querySelector('.container').appendChild(style);
//styles don't apply after the previous line

Изменить для ясности:

Если вы добавите <style></style> тег к <head></head> HTML вы можете применять стили с style.sheet.insertRule(styleString) и добавленные стили будут применяться к документу.

Если вы уже добавили, что <style></style> к <head></head> лайк <head><style></style></head> и попытаться добавить <style></style> где-то еще, как <div><style></style></div> все стили потеряны и больше не применяются.

Это нормально?

Поток кода:

Работает:

  1. присоединять <style> в любом месте
  2. добавить стили с style.sheet.insertRule(styleString)

Не работает:

  1. присоединять <style> в любом месте
  2. добавить стили с style.sheet.insertRule(styleString) в <style>
  3. добавить то же самое <style> где-нибудь еще

Моя другая проблема заключается в том, что стили добавлены в <style></style> не появляться в Firebug даже если они обратились к документу.

Редактировать больше ясности:

Если я возьму style элемент, не изменив таблицу стилей, стили остаются:

var style = document.querySelector('style');
document.head.appendChild(style);
* {color: red}
<p>Hello world</p>

Но если я изменил таблицу стилей с помощью JS, изменения отменяются:

var style = document.querySelector('style'),
    sheet = style.sheet;
sheet.insertRule('* {color: red}', 0);
document.head.appendChild(style); //Comment this line out, and this works.
/* CSS rules will be inserted with JS */
<p>Hello world</p>

1 ответ

Решение

Это потому что <style> элементы имеют только sheet собственности, когда они добавляются в док.
Следовательно, когда вы перемещаете или удаляете его из документа, их sheet свойство возвращается null, Все правила, которые вы применили к нему, используя insertRule метод исчезнет, ​​так как они не внутри <style> "s innerHTML,


Соответствующая часть спецификаций:

Обновление style блочный алгоритм для CSS (text/css) как следует:

  1. Пусть element будет элементом стиля.

  2. Если элемент имеет связанную таблицу стилей CSS, удалите соответствующую таблицу стилей CSS.

  3. Если элемент отсутствует в документе, отмените эти шаги.

  4. Если встроенное поведение элемента Should должно быть заблокировано политикой безопасности содержимого [...], прервите эти шаги. [СНТ]

  5. Создайте таблицу стилей CSS со следующими свойствами: ...

Как видите, каждый раз <style> элемент обновляется, создается новая таблица стилей CSS (только если .3 и .4 не блокируют процесс).


Небольшая демонстрация:

var style = document.createElement('style');
snippet.log('before being appended : '+ style.sheet)
document.body.appendChild(style); 
snippet.log('after being appended : '+ style.sheet)
document.body.removeChild(style);
snippet.log('after being removed : '+ style.sheet)
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

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