Css-bestand direct vervangen (en de nieuwe stijl toepassen op de pagina)

Ik heb een pagina met <link>in de kop die de CSS laadt met de naam light.css. Ik heb ook een bestand met de naam dark.css. Ik wil een knop om de stijl van de pagina in zijn geheel om te wisselen (er worden 40 selectors gebruikt in het CSS-bestand en sommige komen niet overeen in twee bestanden).

Hoe kan ik de verwijzing naar light.cssmet JS verwijderen en alle toegepaste stijlen verwijderen en vervolgens dark.cssladen en alle stijlen toepassen? Ik kan niet zomaar alle elementen resetten, aangezien sommige stijlen worden toegepast via verschillende CSS-bestanden en sommige dynamisch worden gegenereerd door JS. Is er een eenvoudige, maar effectieve manier om dat te doen zonder de pagina opnieuw te laden? Vanilla JS heeft de voorkeur, maar ik zal jQuery sowieso gebruiken voor latere verwerking, dus jQ is ook prima.


Antwoord 1, autoriteit 100%

U kunt alle stylesheets in het document opnemen en ze vervolgens indien nodig activeren/deactiveren.

Als ik de specificatie lees, zou je in staat moeten zijn om een alternatieve stylesheet te activeren door de disabledervan te wijzigen eigenschap van true naar false, maar alleen Firefox lijkt dit correct te doen.

Dus ik denk dat je een paar opties hebt:

Toggle 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>

Instellen en schakelen 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>

Toggle 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>

Je kunt een stylesheet-knooppunt selecteren met getElementById, querySelector, enz.

(Vermijd de niet-standaard <link disabled>. Instelling HTMLLinkElement#disabledis echter prima.)


Antwoord 2, autoriteit 92%

U kunt een nieuwe link maken en de oude door de nieuwe vervangen. Als je het in een functie stopt, kun je het hergebruiken waar het nodig is.

Het 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(cssLinkIndex).replaceChild(newlink, oldlink);
}

De 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>

Voor de eenvoud heb ik inline javascript gebruikt. In productie zou je onopvallende gebeurtenisluisteraars willen gebruiken.


Antwoord 3, autoriteit 19%

Als u een ID instelt op het link-element

<link rel="stylesheet" id="stylesheet" href="stylesheet1.css"/>

je kunt het targeten met Javascript

document.getElementsByTagName('head')[0].getElementById('stylesheet').href='stylesheet2.css';

of gewoon..

document.getElementById('stylesheet').href='stylesheet2.css';

Hier is een uitgebreider voorbeeld:

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

Antwoord 4, autoriteit 13%

Deze vraag is vrij oud, maar ik zou een benadering voorstellen die hier niet wordt genoemd, waarbij je beide CSS-bestanden in de HTML opneemt, maar de CSS zal er zo uitzien

light.css

/*** light.css ***/
p.main{
   color: #222;
}
/*** other light CSS ***/

en dark.csszullen zijn als

/*** dark.css ***/
.dark_layout p.main{
   color: #fff;
   background-color: #222;
}
/*** other dark CSS ***/

in principe zal elke selector in dark.css een kind zijn van .dark_layout

Het enige wat u hoeft te doen is de klasse van het body-element te wijzigen als iemand ervoor kiest om het thema van de website te wijzigen.

$("#changetheme").click(function(){
   $("body").toggleClass("dark_layout");
});

En nu hebben al je elementen de donkere CSS zodra de gebruiker op #changethemeklikt. Dit is heel gemakkelijk te doen als u CSS-preprocessors gebruikt.

Je kunt ook CSS-animaties voor achtergronden en kleuren toevoegen, waardoor de overgang zeer soepel verloopt.


Antwoord 5, autoriteit 10%

Met jQuery kun je het css-bestand zeker omwisselen. Doe dit door op de knop te klikken.

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

Of als sam’s antwoord, dat werkt ook. Hier is de jQuery-syntaxis.

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

Antwoord 6, autoriteit 5%

Met jQuery .attr()kunt u hrefvan uw linktag.i.e

instellen

Voorbeeldcode

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

Antwoord 7

Misschien denk ik te ingewikkeld, maar aangezien het geaccepteerde antwoord niet voor mij werkte, dacht ik dat ik mijn oplossing ook zou delen.

Verhaal:
Wat ik wilde doen, was verschillende ‘skins’ van mijn pagina in de kop opnemen als extra stylesheets die werden toegevoegd aan de ‘hoofd’-stijl en ze omwisselen door op een knop op de pagina te drukken (geen browserinstellingen of zo).

Probleem:
Ik dacht dat de oplossing van @sam erg elegant was, maar het werkte helemaal niet voor mij. Ten minste een deel van het probleem is dat ik één hoofd-CSS-bestand gebruik en er gewoon andere als ‘skins’ aan toevoeg en dus moest ik de bestanden groeperen met de eigenschap ontbrekende ‘title’.

Dit is wat ik heb bedacht.
Voeg eerst alle ‘skins’ toe aan het hoofd met ‘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=''>

Merk op dat ik het hoofd-CSS-bestand de titel=’main’ heb gegeven en dat alle andere een class=’style-skin’ en geen titel hebben.

Om de skins te wisselen, gebruik ik jQuery. Ik laat het aan de puristen over om een ​​elegante VanillaJS-versie te vinden:

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++
});

Wat het doet, is dat het alle beschikbare skins doorloopt, de (binnenkort) actieve skin neemt, de titel op ‘main’ zet en deze activeert. Alle andere skins zijn uitgeschakeld en de titel is verwijderd.


Antwoord 8

Werk eenvoudig uw Linkhref-kenmerk bij naar uw nieuwe css-bestand.

function setStyleSheet(fileName){
       document.getElementById("WhatEverYouAssignIdToStyleSheet").setAttribute('href', fileName);
    }

Other episodes