如何使用jQuery切换样式表?

4

我设计了一个多彩模板,现在我想在点击颜色图标时只更改“CSS”文件,有人可以帮帮我吗?

这是我的代码,但它的效果不好,只能更改一次颜色。

$(document).ready(function() {
  $("a.silver").click(function() {
    $("a.silver").append('<link rel="stylesheet" type="text/css" href="themes/silver/css/template.css"/>');
  });

  $("a.red").click(function() {
    $("a.red").append('<link rel="stylesheet" type="text/css" href="css/template.css"/>');
  });
});

5
不要这样做,改用切换类的方式。 - Matt Ball
@MattBall 我不知道为什么,所以我才问的。我会选择交换样式表。只更改类听起来不对 - 它无法很好地扩展。 - Alnitak
3个回答

3

因此,就像一些评论所说的那样,您最好切换 CSS 类。但是,如果您要更改整个页面样式,则我认为交换样式表似乎是一个不错的主意。但是,在每次想要交换样式表时“重新生成”元素是不必要的。您最好只在需要时将它们从 DOM 中分离。因此,可以使用以下代码:

$(document).ready(function() {
    var sheets = { //a map of sheets. Simply add sheets to this to add more themes (and create appropriate links to them)
        silver: $('<link rel="stylesheet" type="text/css" href="themes/silver/css/template.css"/>'),
        red: $('<link rel="stylesheet" type="text/css" href="css/template.css"/>')
    };

    var currentSheet = sheets.red.appendTo($("head")); //attach default sheet

    $("a.swapStyle").click(function () {
         currentSheet.detach(); //remove the current sheet
         currentSheet = (sheets[$(this).attr("data-theme")]).appendTo($("head")); //attach a new sheet and set the currentSheet variable to remember it.
    });
});

您需要将链接更改为以下格式:
<a href="javascript:void(0)" class="swapStyle" data-theme="red">Change to red theme</a>
<a href="javascript:void(0)" class="swapStyle" data-theme="silver">Change to silver theme</a>

这是最接近我的方法,而且对于超过两种颜色方案来说,这种方法会非常有效。但我仍然想知道为什么有人争论切换类。类不应该代表特定的颜色等,类应该保持不变,而这些类的样式应该改变。 - Alnitak
另一方面,仅使用.detach()来删除当前工作表仍会使其在内存中挂起... - Alnitak
@Alnitak 我使用detach是因为在切换回先前的主题时可以节省一些处理时间,但代价是会消耗一些内存。这是一个权衡,开发者可以选择忽略它。 - Pete
@SabryMuhamadSabry 如果您想在切换页面时保留主题,您需要使用cookie。您可以修改我的代码来实现这一点,通过让currentSheet保存工作表的键而不是工作表本身,然后在更改时将currentSheet保存到cookie中,在页面加载时从cookie中恢复。 - Pete
@Pete 我的看法是,你链接的那个例子是一个非常愚蠢的主题交换方式。它会一直在内存中保留每个主题,并使 CSS 解析和维护变得可怕。 - Alnitak
显示剩余5条评论

1

必须将CSS链接添加到头部

             $(document).ready(function() {
               //load silver automatically in ready

                 $("a.silver").click(function() {
                         $('head > link').last().remove();   //removes red and adds silver
                         $('head').append('<link rel="stylesheet" href="style2.css" type="text/css" />');
                   });

                 $("a.red").click(function() {
                        $('head > link').last().remove();  //remove silver - adds red
                        .append('<link rel="stylesheet" type="text/css" href="themes/silver/css/template.css"/>');
                          });
                    });
             });

我的jQuery中实际的样式表不正确


@ScottSelby所编写的“silver”样式表将会增强(和/或覆盖)原始样式表,而不是替换它。这将使页面渲染器需要更多的工作。 - Alnitak
@Alnitak - .toggleClass 是动态更改样式的首选方式 - 他特别想要“添加或删除样式表”。 - Scott Selby

1

如先前所提到的,也许最好的做法是切换CSS样式而非文件,但如果必须切换文件,请尝试以下方法:

$(function(){
    $('a.silver').click(function (){
       $('link[href="css/template.css"]').attr('href','themes/silver/css/template.css');
    });
    $('a.red').click(function (){
       $('link[href="themes/silver/css/template.css"]').attr('href','css/template.css');
    });
});

在这个解决方案中,您还必须像往常一样在头部定义样式...

@SabryMuhamadSabry 在我看来,Pete的回答更好。 - Alnitak
@Alnitak他为不重新生成整个样式标签提供了支持,但是您没有提供任何防御,说明为什么这个答案无效。 - r0m4n
@r0m4n 我没有说你的回答无效,我是说Pete的回答更好。他的回答可以轻松地扩展到超过两个备选主题,而你的则不能。 - Alnitak
那不是他的问题:“如何使用jQuery切换样式表?”在他目前的答案中,没有任何样式表会在禁用js时加载。 - r0m4n
哦,真的吗?我尝试了超过两个主题的“r0m4n”代码,它可以工作!...而且我仍然更喜欢“r0m4n”代码,因为我写得更少 :) - Sabry Muhamad Sabry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接