jQuery 动态替换 css 文件(并将新样式应用到页面)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19844545/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 00:43:06  来源:igfitidea点击:

Replacing css file on the fly (and apply the new style to the page)

javascriptjqueryhtmlcss

提问by Xeos

I have a page which has <link>in the header that loads the CSS named light.css. I also have a file named dark.css. I want a button to swap the style of the page all together (there are 40 selectors used in css file and some do not match in two files).

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

How can I remove reference to light.csswith JS and remove all the styles that were applied and then load dark.cssand apply all the styles from that? I can't simply reset all of the elements, since some of the styles are applied through different css files and some are dynamically generated by JS. Is there a simple, yet effective way to do that without reloading the page? Vanilla JS is preferable, however I will use jQuery for later processing anyways, so jQ is also fine.

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

采纳答案by Matthew Johnson

You can create a new link, and replace the old one with the new one. If you put it in a function, you can reuse it wherever it's needed.

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

The Javascript:

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

The HTML:

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>

For simplicity, I used inline javascript. In production you would want to use unobtrusive event listeners.

为简单起见,我使用了内联 javascript。在生产中,您可能希望使用不显眼的事件侦听器。

回答by sam

You can include all the stylesheets in the document and then activate/deactivate them as needed.

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

In my reading of the spec, you should be able to activate an alternate stylesheet by changing its disabledproperty from true to false, but only Firefox seems to do this correctly.

在我阅读规范时,您应该能够通过将其disabled属性从 true更改为 false激活备用样式表,但似乎只有 Firefox 才能正确执行此操作。

So I think you have a few options:

所以我认为你有几个选择:

Toggle rel=alternate

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

Set and toggle disabled

设置和切换 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

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

You can select a stylesheet node with getElementById, querySelector, etc.

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

(Avoid the nonstandard <link disabled>. Setting HTMLLinkElement#disabledis fine though.)

(避免非标准的<link disabled>。不过设置HTMLLinkElement#disabled很好。)

回答by davidcondrey

If you set an ID on the link element

如果您在链接元素上设置了 ID

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

you can target it with Javascript

你可以用 Javascript 定位它

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

or just..

要不就..

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


Here's a more thorough example:

这是一个更彻底的例子:

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

回答by void

This question is pretty old but I would suggest an approach which is not mentioned here, in which you will include both the CSS files in the HTML, but the CSS will be like

这个问题已经很老了,但我建议采用一种此处未提及的方法,在该方法中,您将在 HTML 中包含两个 CSS 文件,但 CSS 将类似于

light.css

光.css

/*** light.css ***/

p.main{
   color: #222;
}

/*** other light CSS ***/

and dark.csswill be like

dark.css会像

/*** dark.css ***/

.dark_layout p.main{
   color: #fff;
   background-color: #222;
}

/*** other dark CSS ***/

basicall every selector in dark.css will be a child of .dark_layout

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

Then all you need to do is to change the class of body element if someone selects to change the theme of the website.

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

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

And now all your elements will have the dark css once the user clicks on #changetheme. This is very easy to do if you are using any kind of CSS preprocessors.

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

You can also add CSS animations for backgrounds and colors which makes the transition highly smooth.

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

回答by Krishna

Using jquery you can definitely swap the css file. Do this on button click.

使用 jquery 你绝对可以交换 css 文件。单击按钮时执行此操作。

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

Or as sam's answer, that works too. Here is the jquery syntax.

或者作为山姆的回答,这也有效。这是 jquery 语法。

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

回答by Satinder singh

Using jquery .attr()you can set hrefof your link tag.i.e

使用jQuery .attr()可以设置 HREF你的链接标签.IE

Sample code

示例代码

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

回答by Hanzla Habib

Simply update you Linkhref attribute to your new css file.

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

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

回答by Flow

Maybe I'm thinking too complicated, but since the accepted answer was not working for me I thought I'd share my solution as well.

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

Story:
What I wanted to do was to include different 'skins' of my page in the head as additional stylesheets that where added to the 'main' style and switch them by pressing a button on the page (no browser settings or stuff).

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

Problem:
I thought @sam's solution was very elegant but it did not work at all for me. At least part of the problem is that I'm using one main CSS file and just add others on top as 'skins' and thus I had to group the files with the missing 'title'property.

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

Here is what I came up with.
First add all 'skins' to the head using 'alternate':

这是我想出的。
首先使用“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=''>

Note that I gave the main CSS file the title='main' and all others have a class='style-skin' and no title.

To switch the skins I'm using jQuery. I leave it up to the purists to find an elegant VanillaJS version:

请注意,我给主 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++
});

What it does is it iterates over all available skins, takes the (soon) active one, sets the title to 'main' and activates it. All other skins are disabled and title is removed.

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