快速替换css文件(并将新样式应用于页面)


71

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

如何删除light.css与JS的引用并删除所有已应用的样式,然后dark.css从中加载并应用所有样式?我不能简单地重置所有元素,因为某些样式是通过不同的CSS文件应用的,而某些样式是由JS动态生成的。是否有一种简单但有效的方法来执行此操作而无需重新加载页面?最好使用Vanilla JS,但是无论如何我都会使用jQuery进行后续处理,因此jQ也很好。


1
我选择了Mattew的答案,因为使用该方法,我可以轻松地扩展for()循环以处理多个文件和交换light以及dark其他脚本/样式表。
Xeos

Answers:


70

您可以创建一个新链接,然后用新链接替换旧链接。如果将其放在函数中,则可以在需要的地方重复使用它。

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。在生产中,您需要使用不引人注目的事件侦听器。


9
我认为仅更新href属性可能同样有效:oldlink.href = cssFile; // done
sam 2013年

真正。这将替换DOM中的整个链接节点。
马修·约翰逊

如果您想提取实时重载类型的东西,这可能是解决问题的方法,因为href可能是相同的,并且如果href并没有实际更改,浏览器可能实际上不执行任何操作。
flcoder 2015年

1
在切换CSS文件时,下载文件和呈现样式方面的差距使html没有样式。我猜应该有一个默认的样式表,它会一直添加基本样式。移动浏览器只需花费大量时间来替换CSS样式表。同样,鉴于jekyll生成的静态网站,链接的索引可能在不同的页面中有所不同
Irshad

您可以使用绝对URL来绕过位于不同文件夹中的页面。我喜欢默认样式表的想法,以防止显示FOUC。不错的提示!
马修·约翰逊

79

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

在阅读规范时,您应该能够通过将其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>

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

(避免使用非标准方法<link disabled>。但是设置HTMLLinkElement#disabled很好。)


@sam现在,很抱歉我不能接受别人的问题:)...仅对页面性能有影响吗?在该属性设置为false之前,浏览器会忽略禁用的链接吗?
dzenesiz 2015年

8
不幸disabled的是,不鼓励将其设置为属性:“将disable用作HTML属性是非标准的,仅由某些浏览器使用(W3#27677)。请勿使用它。” -> developer.mozilla.org/zh-CN/docs/Web/HTML/Element/…–
丹尼尔(Daniel)

@dzenesiz浏览器可以跳过下载备用样式表,直到需要它为止,但我不知道它们的实际行为。
SAM

3
只是为了澄清@Daniel所说的内容,HTML属性是非标准的,但是根据Mozilla的说法,DOM属性是IS。因此,以上述方式使用javascript进行切换实际上是符合标准的。除非我缺少任何东西,否则这应该是公认的答案。
emersonthis

1
CSS对象模型说,这对disabled标志:“注意:即使取消它并不一定意味着CSS样式表实际上是用于渲染”。这可能是答案在Firefox上有效但在Webkit&Blink(EpyphanyChromium)上无效的原因
Cristian Ciupitu

14

如果在链接元素上设置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>

8

使用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);

1
可能会更好,但是我喜欢您如何清楚地定义sam的jQ部分并帮助我清楚地了解所有内容。
RozzA

8

这个问题已经很老了,但我建议您不要在这里提到的一种方法,您将在HTML中包含两个CSS文件,但是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 ***/

basic.dark.css中的每个选择器都将是 .dark_layout

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

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

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

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


4

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

样例代码

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

0

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

故事:
我想做的是将页面的不同“皮肤”作为其他样式表添加到“主要”样式中,并通过按页面上的按钮来切换它们(没有浏览器设置或内容)。

问题:
我认为@sam的解决方案非常优雅,但是对我来说根本不起作用。问题的至少一部分是,我使用了一个主CSS文件,并且仅将其他文件添加为“皮肤”,因此我不得不使用缺少的“ title”属性对文件进行分组。

这是我想出的。
首先使用“ alternate”将所有“ skins”添加到头部:

<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

只需将Linkhref属性更新为新的CSS文件即可。

function setStyleSheet(fileName){
       document.getElementById("WhatEverYouAssignIdToStyleSheet").setAttribute('href', fileName);
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.