Замена css файла на лету (и применение нового стиля к странице)
У меня есть страница с <link>
в заголовке, которая загружает CSS с именем light.css
. У меня также есть файл с именем dark.css
. Я хочу, чтобы кнопка меняла стиль страницы вместе (в css файле используется 40 селекторов, а некоторые не совпадают в двух файлах).
Как удалить ссылку на light.css
с помощью JS и удалить все стили, которые были применены, а затем загрузить dark.css
и применить к ней все стили? Я не могу просто reset всех элементов, так как некоторые стили применяются через разные файлы css, а некоторые из них динамически генерируются JS. Есть ли простой, но эффективный способ сделать это без перезагрузки страницы? Vanilla JS предпочтительнее, однако я буду использовать jQuery для последующей обработки в любом случае, поэтому jQ также прекрасен.
Ответы
Ответ 1
Вы можете создать новую ссылку и заменить старую на новую. Если вы поместите его в функцию, вы можете использовать его везде, где нужно.
Javascript:
function changeCSS(cssFile, cssLinkIndex) {
var oldlink = document.getElementsByTagName("link").item(cssLinkIndex);
var newlink = document.createElement("link");
newlink.setAttribute("rel", "stylesheet");
newlink.setAttribute("type", "text/css");
newlink.setAttribute("href", cssFile);
document.getElementsByTagName("head").item(0).replaceChild(newlink, oldlink);
}
HTML:
<html>
<head>
<title>Changing CSS</title>
<link rel="stylesheet" type="text/css" href="positive.css"/>
</head>
<body>
<a href="#" onclick="changeCSS('positive.css', 0);">STYLE 1</a>
<a href="#" onclick="changeCSS('negative.css', 0);">STYLE 2</a>
</body>
</html>
Для простоты я использовал встроенный javascript. В производстве вы хотели бы использовать ненавязчивых слушателей событий.
Ответ 2
Вы можете включить все таблицы стилей в документ, а затем активировать/деактивировать их по мере необходимости.
При чтении спецификации вы можете активировать альтернативную таблицу стилей, изменив ее disabled
свойство от true до false, но только Firefox, похоже, делает это правильно.
Поэтому я думаю, что у вас есть несколько вариантов:
Переключить rel=alternate
<link rel="stylesheet" href="main.css">
<link rel="stylesheet alternate" href="light.css" id="light" title="Light">
<link rel="stylesheet alternate" href="dark.css" id="dark" title="Dark">
<script>
function enableStylesheet (node) {
node.rel = 'stylesheet';
}
function disableStylesheet (node) {
node.rel = 'alternate stylesheet';
}
</script>
Установить и disabled
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="light.css" id="light" class="alternate">
<link rel="stylesheet" href="dark.css" id="dark" class="alternate">
<script>
function enableStylesheet (node) {
node.disabled = false;
}
function disableStylesheet (node) {
node.disabled = true;
}
document
.querySelectorAll('link[rel=stylesheet].alternate')
.forEach(disableStylesheet);
</script>
Переключить media=none
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="light.css" media="none" id="light">
<link rel="stylesheet" href="dark.css" media="none" id="dark">
<script>
function enableStylesheet (node) {
node.media = '';
}
function disableStylesheet (node) {
node.media = 'none';
}
</script>
Вы можете выбрать узел таблицы стилей с getElementById, querySelector и т.д.
(Избегайте нестандартного <link disabled>
. Установка HTMLLinkElement # отключена, хотя.)
Ответ 3
С помощью jquery вы можете поменять файл css. Сделайте это нажатием кнопки.
var cssLink = $('link[href*="light.css"]');
cssLink.replaceWith('<link href="dark.css" type="text/css" rel="stylesheet">');
Или как ответ sam, который тоже работает. Вот синтаксис jquery.
$('link[href*="light.css"]').prop('disabled', true);
$('link[href*="dark.css"]').prop('disabled', false);
Ответ 4
Если вы установили идентификатор элемента ссылки
<link rel="stylesheet" id="stylesheet" href="stylesheet1.css"/>
вы можете настроить его с помощью Javascript
document.getElementsByTagName('head')[0].getElementById('stylesheet').href='stylesheet2.css';
или просто..
document.getElementById('stylesheet').href='stylesheet2.css';
Вот более подробный пример:
<head>
<script>
function setStyleSheet(url){
var stylesheet = document.getElementById("stylesheet");
stylesheet.setAttribute('href', url);
}
</script>
<link id="stylesheet" rel="stylesheet" type="text/css" href="stylesheet1.css"/>
</head>
<body>
<a onclick="setStyleSheet('stylesheet1.css')" href="#">Style 1</a>
<a onclick="setStyleSheet('stylesheet2.css')" href="#">Style 2</a>
</body>
Ответ 5
Этот вопрос довольно старый, но я бы предложил подход, который здесь не упоминается, в который вы будете включать оба CSS файла в HTML, но CSS будет подобен
light.css
/*** light.css ***/
p.main{
color: #222;
}
/*** other light CSS ***/
и dark.css будет как
/*** dark.css ***/
.dark_layout p.main{
color: #fff;
background-color: #222;
}
/*** other dark CSS ***/
basicall каждый селектор в dark.css будет дочерним .dark_layout
Затем все, что вам нужно сделать, это изменить класс элемента body, если кто-то выбирает тему темы веб-сайта.
$("#changetheme").click(function(){
$("body").toggleClass("dark_layout");
});
И теперь все ваши элементы будут иметь темный css, как только пользователь нажмет на #changetheme
. Это очень легко сделать, если вы используете какие-либо препроцессоры CSS.
Вы также можете добавить анимацию CSS для фона и цветов, что делает переход очень гладким.
Ответ 6
Используя jquery .attr(), вы можете установить href вашего тега ссылки .i.e
Пример кода
$("#yourButtonId").on('click',function(){
$("link").attr(href,yourCssUrl);
});
Ответ 7
Возможно, я думаю слишком сложно, но поскольку принятый ответ не работал на меня, я думал, что тоже поделюсь своим решением.
История:
То, что я хотел сделать, это включить различные "скины" моей страницы в голове в качестве дополнительных таблиц стилей, которые добавлены в "основной" стиль и переключают их, нажимая кнопку на странице (без настроек браузера или других вещей).
Проблема:
Я думал, что решение @sam было очень элегантным, но для меня это не сработало. По крайней мере, часть проблемы заключается в том, что я использую один основной файл CSS и просто добавляю других сверху в качестве "скинов", и поэтому мне пришлось сгруппировать файлы с свойством отсутствующего заголовка.
Вот что я придумал.
Сначала добавьте все "скины" в голову, используя "alternate":
<link rel="stylesheet" href="css/main.css" title='main'>
<link rel="stylesheet alternate" href="css/skin1.css" class='style-skin' title=''>
<link rel="stylesheet alternate" href="css/skin2.css" class='style-skin' title=''>
<link rel="stylesheet alternate" href="css/skin3.css" class='style-skin' title=''>
Обратите внимание, что я дал основному файлу CSS заголовок = 'main', а все остальные имеют стиль class= 'и не имеют названия.
Для переключения скинов я использую jQuery. Я оставляю это для пуристов, чтобы найти элегантную версию VanillaJS:
var activeSkin = 0;
$('#myButton').on('click', function(){
var skins = $('.style-skin');
if (activeSkin > skins.length) activeSkin=0;
skins.each(function(index){
if (index === activeSkin){
$(this).prop('title', 'main');
$(this).prop('disabled', false);
}else{
$(this).prop('title', '');
$(this).prop('disabled', true);
}
});
activeSkin++
});
Что он делает, он выполняет итерацию по всем доступным скинам, принимает (скоро) активный, устанавливает заголовок в "main" и активирует его. Все остальные скины отключены и название удалено.