86

我有一个页面,它<link>在标题中加载名为light.css. 我还有一个名为dark.css. 我想要一个按钮来一起交换页面的样式(css文件中使用了40个选择器,有些在两个文件中不匹配)。

如何删除对light.cssJS 的引用并删除所有已应用的样式,然后dark.css从中加载并应用所有样式?我不能简单地重置所有元素,因为有些样式是通过不同的 css 文件应用的,有些是由 JS 动态生成的。有没有一种简单而有效的方法可以在不重新加载页面的情况下做到这一点?Vanilla JS 更可取,但是无论如何我都会使用 jQuery 进行后续处理,所以 jQ 也可以。

4

8 回答 8

83

您可以在文档中包含所有样式表,然后根据需要激活/停用它们。

在我阅读规范时,您应该能够通过将其属性从 true 更改为 false来激活备用样式表disabled,但似乎只有 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>

您可以使用getElementByIdquerySelector等选择样式表节点。

(避免使用非标准的<link disabled>. 设置HTMLLinkElement#disabled很好。)

于 2013-11-07T19:20:53.587 回答
77

您可以创建一个新链接,并将旧链接替换为新链接。如果你把它放在一个函数中,你可以在任何需要的地方重用它。

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

的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。在生产中,您可能希望使用不显眼的事件侦听器。

于 2013-11-07T19:17:06.877 回答
17

如果在链接元素上设置 ID

<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>
于 2015-05-13T02:06:05.463 回答
11

这个问题已经很老了,但我会建议一种这里没有提到的方法,在这种方法中,您将在 HTML 中包含两个 CSS 文件,但 CSS 就像

光.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 ***/

基本上,dark.css 中的每个选择器都是.dark_layout

如果有人选择更改网站的主题,您需要做的就是更改 body 元素的类。

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

现在,一旦用户单击,您的所有元素都将具有深色 css #changetheme。如果您使用任何类型的 CSS 预处理器,这很容易做到。

您还可以为背景和颜色添加 CSS 动画,使过渡非常平滑。

于 2018-02-14T20:54:28.367 回答
8

使用 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);
于 2013-11-07T19:19:54.570 回答
4

使用 jquery .attr()您 可以设置 链接标签的href .ie

示例代码

$("#yourButtonId").on('click',function(){
   $("link").attr(href,yourCssUrl);
});
于 2013-11-07T19:32:05.193 回答
0

也许我想得太复杂了,但由于接受的答案对我不起作用,我想我也会分享我的解决方案。

故事:
我想做的是在头部包含我页面的不同“皮肤”作为附加样式表,这些样式表添加到“主要”样式中,并通过按下页面上的按钮来切换它们(没有浏览器设置或其他东西)。

问题:
我认为@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 文件赋予了 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++
});

它的作用是遍历所有可用的皮肤,获取(即将)激活的皮肤,将标题设置为“主”并激活它。所有其他皮肤都被禁用并且标题被删除。

于 2017-04-04T14:29:59.710 回答
0

只需将您Link的 href 属性更新为新的 css 文件。

function setStyleSheet(fileName){
       document.getElementById("WhatEverYouAssignIdToStyleSheet").setAttribute('href', fileName);
    }
于 2020-01-29T08:29:51.540 回答