it-roy-ru.com

Замена файла CSS на лету (и применить новый стиль к странице)

У меня есть страница с <link> в заголовке, которая загружает CSS с именем light.css. У меня также есть файл с именем dark.css. Я хочу кнопку, чтобы поменять стиль страницы все вместе (есть 40 селекторов, используемых в файле CSS, и некоторые не совпадают в двух файлах).

Как я могу удалить ссылку на light.css с помощью JS и удалить все примененные стили, а затем загрузить dark.css и применить все стили из этого? Я не могу просто сбросить все элементы, так как некоторые стили применяются через разные CSS-файлы, а некоторые динамически генерируются JS. Есть ли простой, но эффективный способ сделать это без перезагрузки страницы? Vanilla JS предпочтительнее, однако я все равно буду использовать jQuery для дальнейшей обработки, так что jQ тоже подойдет.

48
Xeos

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

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. В производстве вы хотели бы использовать ненавязчивые слушатели событий.

50
Matthew Johnson

Вы можете включить все таблицы стилей в документ, а затем активировать/деактивировать их по мере необходимости.

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

64
sam

Используя jquery, вы определенно можете поменять файл css. Сделайте это по нажатию кнопки.

var cssLink = $('link[href*="light.css"]');
cssLink.replaceWith('<link href="dark.css" type="text/css" rel="stylesheet">');

Или как ответ Сэма , это тоже работает. Вот синтаксис jquery.

$('link[href*="light.css"]').prop('disabled', true);
$('link[href*="dark.css"]').prop('disabled', false);
7
Krishna

Если вы установите идентификатор на элементе ссылки

<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>
6
davidcondrey

Этот вопрос довольно старый, но я бы предложил подход, который здесь не упоминается, в котором вы включите оба файла 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-анимацию для фона и цветов, что делает переход очень плавным.

5
void

Используя jquery .attr () вы можете установить href вашего тега link .i.e 

Образец кода

$("#yourButtonId").on('click',function(){
   $("link").attr(href,yourCssUrl);
});
4
Satinder singh

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

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

Проблема:
Я думал, что решение @ sam было очень элегантным, но у меня оно не сработало. По крайней мере, часть проблемы заключается в том, что я использую один основной файл CSS и просто добавляю другие сверху в качестве «скинов», и поэтому мне пришлось сгруппировать файлы со свойством missing «title».

Вот что я придумал.
Сначала добавьте все «скины» в голову, используя «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-файлу title = 'main', а все остальные имеют class = 'style-skin' и не имеют заголовка.

Для переключения скинов я использую 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' и активирует его. Все остальные скины отключены, а заголовок удален.

0
Flow