如何切换外部CSS文件?

5
我有几本关于AJAX的书,但还是很新。所有的教程和书籍都有一个无处不在的例子:自动填充搜索栏和异步表单验证器。这些都很好,但不是我想要的。具体而言,我想点击一个按钮并在我的头文件中包含的外部CSS文件中切换。这可能吗?嗯...我知道这是可能的,但你怎么做呢?
附注:我在这个项目中使用了jQuery,所以如果有从中构建的东西,那就更好了!
另外,我意识到我没有包含重要信息(不要开枪!):
1. 最终目标是拥有一个用户设置部分,用户可以点击单选按钮并决定他们想要用于我们应用程序的颜色方案。因此,我们最终将有大约8种不同的CSS样式可供选择。不确定这是否会改变实现此目标的最佳方法。
2. 用户正在登录其帐户并在那里更改其设置。我希望他们的更改能够“保持”,直到他们再次决定更改样式表。我可以在MySQL中手动完成此操作,因为我们有一个名为stylesheets的表格,其中包含各种用户样式表编号...因此,实际上,我需要异步更改该MySQL值,以便立即加载CSS。
6个回答

16

为 CSS link 标签添加 id 属性,以便使用 JavaScript 操纵该标签:

<link id="cssfile" href="css/avocado.css" type="text/css" rel="stylesheet">

设置 href 属性的 JavaScript 代码如下:

document.getElementById('cssfile').href = 'css/carrot.css';

用户可以通过点击链接来调整颜色:

<a href="#"
 onclick="document.getElementById('cssfile').href='css/carrot.css';">Carrots</a>

通过更改媒体类型,这也可以让用户快速更改打印布局、移动设备(或平板电脑)上的首选布局等。

此解决方案不需要使用jQuery。

另请参阅:http://www.webmasterworld.com/forum91/4554.htm


4

使用 jQuery 实现样式表切换器。

针对“入门者后续”的评论,我将尽力让它更具指导性。

我在编写时用来测试的页面可以在这里找到。

页面显示

您需要在每个页面的 <head> 中以 <link> 标签的形式显示当前样式表。该 <link> 标签将需要一个 id 以供稍后在 JavaScript 中引用。例如:

<?php 
  // Somewhere in the server side code, $current_stylesheet is read from the user's 
  // "preferences" - most likely from a database / session object
  $current_stylesheet = $user->stylesheet;
?>
<link href='<?php echo $current_stylesheet ?>' rel='stylesheet' type='text/css' id='stylelink' />

更改偏好设置

一旦您显示了用户的样式表,您需要一种方法来更改它。创建一个<form>,当用户更改其样式表时,将向服务器发送请求:

<form method="GET" id="style_form" >
  <select name="stylesheet" id="styleswitch">
    <option value="css1.css">Black &amp; White</option>
    <option value="css2.css" selected="selected">Shades of Grey</option>
   </select>
   <input value='save' type='submit' />
</form>

服务器端

现在,如果没有使用jQuery,提交这个表格应该是GET方式(如果你喜欢也可以改为POST方式)stylesheet={new stylesheet} 在当前页面上。因此,在您的引导/站点包含文件中的某个位置,您需要检查它,以下是一个PHP示例:

$styles = array(
  'css1.css' => 'Black &amp; White',
  'css2.css' => 'Shades of Grey',
);

if (!empty($_GET["sytlesheet"]) {
  // VALIDATE IT IS A VALID STYLESHEET - VERY IMPORTANT
  // $styles is the array of styles:
  if (array_key_exists($_GET["stylesheet"], $styles)) {
    $user->stylesheet = $_GET["stylesheet"];
    $user->save();
  }
}

实时预览

现在,您已经为没有JavaScript的用户创建了一个功能齐全的样式切换器。现在,您可以添加一些jQuery代码,使这一切变得更加优美。您需要使用jQuery表单插件来创建一个漂亮的ajaxForm()函数,用于处理表单提交。请将jQuery和jQuery表单库添加到页面中:

<script type='text/javascript' src='/js/jquery.js'></script>
<script type='text/javascript' src='/js/jquery.form.js'></script>

现在我们已经包含了所需的库 -
$(function() {
  // When everything has loaded - this function will execute:


  $("#style_form").ajaxForm(function() {
    // the style form will be submitted using ajax, when it succeeds:
    // this function is called:
    $("#thediv").text('Now Using: '+$('#styleswitch').val());
  });

  $("#styleswitch").change(function() {
    // When the styleswitch option changes, switch the style's href to preview
    $("#stylelink").attr('href', $(this).val());
    // We also want to submit the form to the server (will use our ajax)
    $(this).closest('form').submit();
  });

  // now that you have made changing the select option submit the form,
  // lets get rid of the submit button
  $("#style_form input[type=submit]").remove();
});

抱歉我有一些新手的跟进问题 1) 所以,为了完成这个,我需要一个样式切换的按钮,对吗?你能给我一个简单的带代码的按钮示例吗? 2) 我能否将保存功能与第一个按钮结合起来?比如说:理想情况下,用户只需点击按钮,CSS就会更改,然后他们就可以完成(或者他们点击另一种颜色,然后完成)。 - Joel
我相信我已经回答了所有的问题... 如果您有任何其他的后续问题,最好提出一个新的问题。 - gnarf
示例链接已失效。 - Artemis

3
这里有一个使用jQuery的示例。
<!DOCTYPE html>
<html>
    <head>
    <link rel="stylesheet" type="text/css" href="style1.css" />
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"
            type="text/javascript"></script>
        <script type="text/javascript">
            $(function(){
                $('#change-css').click(function(e){
                    e.preventDefault();
                    $('link[rel="stylesheet"]').attr('href', 'style2.css');
                });
            });
        </script>
    </head>
    <body>
        <a id="change-css" href="#">change css</a>
    </body>
</html>

操作行是$('link[rel="stylesheet"]').attr('href', 'style2.css');。这会查找任何具有rel="stylesheet"<link>标签,并将其href属性更改为style2.css


1

这与Ajax无关。这与JS和DOM操作有关(搜索教程的一些关键词)。
我正在使用Mootools,它是一个JS库,内置了该功能。
如果您喜欢手动操作,那么我会简单地向添加元素或调整现有元素的href属性。

 <link rel="stylesheet" href="http://sstatic.net/so/all.css?v=6063" id='bobo'>
...
...
...
<script>document.getElementById('bobo').href="http://my.doamin.com/new.css";</script>

如果元素在页眉中,getElementById会触发事件吗? - Andre Pena

1

您还可以加载两个CSS文件,并在第二个文件中的所有选择器前加上一个body类名。

body.secondsheet {}
body.secondsheet a {}
body.secondsheet hr {}

然后你所要做的就是在body标签中添加/删除"secondsheet"类来切换样式表。


0

要将新的CSS文件添加到页面中,只需创建一个新的<link>标签:

function addCss (url) {
    var s = document.createElement('link');
    s.rel = 'stylesheet';
    s.type = 'text/css';
    s.href = url;
    document.getElementsByTagName('head')[0].appendChild(s);
}

addCss('http://path/to/stylesheet.css');

要从页面中删除一个CSS文件,只需将<link>标签移除即可。
function removeCss (search) {
    var css = document.getElementsByTagName('link');
    for (var i=0;i<css.length;i++) {
        var c = css[i];
        if (c.rel === 'stylesheet' || c.type === 'text/css') {
            if (c.href && c.href.match(search)) {
                c.parentNode.removeChild(c);
            }
        }
    }
}

// Remove all css that contains 'mycss_', can use regexp if necessary:
removeCss(/mycss_.*\.css/);

我会将它添加到头部而不是正文,除此之外,看起来很好。 - Itay Moav -Malimovka
1
除了样式方面外,将它添加到 head 而不是 body 没有任何理由。而且,由于这是一个活动 DOM,没有像 Firebug 这样的工具,没有人会注意到样式方面。将它附加到 body 更简单。由于不存在 document.head,将其附加到 head 是繁琐的:document.getElementsByTagName('head')[0].appendChild(s) - slebetman
在正文中不允许链接元素。依赖浏览器执行错误恢复并不是一个好主意(即使当前的浏览器在这种特定情况下能够一致地执行)。 - Quentin
@David:糟糕,忘记了。修复代码以符合HTML规范。 - slebetman

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