#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-файл имеет класс, который используется несколькими элементами, то все эти элементы будут затронуты вскоре после загрузки файла.