Переопределение «на лету» селекторов css-правил файла css с помощью javascript

#javascript #html #css #ecmascript-6

#javascript #HTML #css #ecmascript-6

Вопрос:

У меня есть страница, содержащая тег select, который позволяет изменять тему css страницы «на лету» с помощью некоторого javascript.

Теперь я хочу разрешить изменять стиль css для конкретных HTML-элементов на странице.

Например, у меня есть две таблицы стилей «темы» :

 /* in red theme file 'theme_red.css' */
.title{color:red;}
.text{...}
 
 /* in blue theme file 'theme_blue.css' */
.title{color:blue;}
.text{...}
 

И у меня есть некоторый тег «выбрать» «изменить тему» на странице. Это здесь минималистский пример, в реальном случае количество «тематических» html-элементов и количество таблиц стилей являются модульными.

Я ищу создать функцию javascript, подобную этой: (чистый javascript ES6)

 loadCssThemeFileOnTheFlyForSpecificHtmlElement(idOfSpecificHtmlElement, themeName){
    // 1) Insert a new link tag in the head of the page with href attribute "themeName   '.css'"
    ...

    // 2) for each css rules selector (of the css file ?), override the css selector rule like this : 
    // `.selector1` become `#idOfElement .selector1`
    // `.selector2` become `#idOfElement .selector2`
    // ...
    // `.selectorN` become `#idOfElement .selectorN`

}
 

И я застрял на шаге 2 функции insertCssFileOnTheFly . Возможно ли сделать то, что я хочу, с помощью некоторого javascript?
Я имею в виду, возможно ли зациклить правило css текущей страницы и добавить к каждому правилу селектора строку «#idOfElement»?

Спасибо за любую помощь

Комментарии:

1. В браузере jasvascript работает с DOM, а не с файлом CSS, вы не можете изменять селекторы CSS таким образом

2. Вы хотите применить «синюю» тему к некоторым элементам страницы и «красную» тему к другим?

Ответ №1:

Возможно ли сделать то, что я хочу, с помощью некоторого javascript? Я имею в виду, возможно ли зациклить правило css текущей страницы и добавить к каждому правилу селектора строку «#idOfElement»?

ДА. Используя javascript, вы можете получать доступ к своим таблицам стилей и изменять их содержимое. Например, если у вас есть только один StyleSheet , вы можете ссылаться на него следующим образом:

 document.styleSheets[0]
 

Каждый StyleSheet из них имеет CSSRuleList объект, подобный массиву, содержащий упорядоченную коллекцию объектов CSSRule :

 document.styleSheets[0].cssRules
 

И у каждого CSSRule есть, среди его свойств, selectorText свойство.

Итак, если вы хотите сослаться на selectorText первый CSSRule из ваших первых StyleSheet , вы можете использовать:

 document.styleSheets[0].cssRules[0].selectorText // .selector1
 

Рабочий пример:

 const myCSSRules = document.styleSheets[0].cssRules;

for (let CSSRule of myCSSRules) {

  CSSRule.selectorText = '#my-element '   CSSRule.selectorText;
  console.log(CSSRule.selectorText);

} 
 .selector1 {
  color: red;
  font-weight: 700;
}

.selector2 {
  color: blue;
  font-weight: 700;
} 
 <p class="selector1">Selector 1</p>
<p class="selector2">Selector 2</p>

<div style="border: 1px dashed red; text-align:center;" id="my-element">
  <p class="selector1">Selector 1</p>
  <p class="selector2">Selector 2</p>
</div> 


Дальнейшее чтение:

Ответ №2:

CSS можно удалять или добавлять «на лету» с помощью методов document.head.removeChild() и document.head.appendChild() .

Для удаления существующего css-файла «на лету»:

 var redTheme = document.getElementById('red-theme-css')
document.head.removeChild(redTheme)
 

Чтобы добавить новый css-файл «на лету»:

 var blueTheme = document.createElement('link')
blueTheme.id = "blue-theme-css"
blueTheme.type = "text/css"
blueTheme.rel = "stylesheet"
blueTheme.href = "link-to-blue-theme-css-file"
document.head.appendChild(blueTheme)
 

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

Если требуется изменить стиль только для одного компонента, то загружаемый css-файл должен быть написан таким образом, чтобы в нем были классы, применимые только к конкретному компоненту.

Дополнительная информация:

https://www.w3.org/wiki/Dynamic_style_-_manipulating_CSS_with_JavaScript

Комментарии:

1. Спасибо за вашу помощь! но вопрос не в том, чтобы удалить существующее правило или добавить новый css-файл «на лету» (я знаю, как это сделать), суть в том, как изменить весь загруженный (на лету) css-файл, переопределив его правила (измените все правила, подобные ‘.selector1{}’с помощью ‘#idofspecificelementgiveninjavascriptфункции . selector1{}’ )

2. Загрузка css-файла применит стиль на уровне документа, и это может повлиять на все компоненты. Если требуется применить css к определенному элементу «на лету», с помощью загрузки css-файла, то загружаемый CSS-файл должен иметь классы, которые применяются только к определенному элементу. Если загружаемый css-файл имеет класс, который используется несколькими элементами, то все эти элементы будут затронуты вскоре после загрузки файла.