【问题标题】:How can I change the css class rules using jQuery?如何使用 jQuery 更改 css 类规则?
【发布时间】:2010-10-11 22:47:10
【问题描述】:

谁能帮帮我,我的问题有两个部分。

  1. 我想做的是使用 jQuery 即时更改 css 类规则。

    .classname{color:red;字体大小:14px;}

    在上面的示例中,我有一个名为 .classname 的类,现在使用 jQuery 我只想更改字体大小而不是 .classname 中的颜色,而不是通过添加 css inline。

  2. 我想创建 .classname 更改并将其保存到文件中,记住将有完整的样式表或没有将保存在文件中的类名。

我怎样才能以最简单和更好的方式做到这一点?

谢谢!

【问题讨论】:

  • 如果你想添加 :hover 和 :active 规则,这一点尤其重要,这不能用 $.css() 来完成。

标签: jquery css


【解决方案1】:

据我所知,没有 jQuery 方法可以做到这一点。可能有一些 jQuery 插件,但我不知道。

基本上,您在第一个问题中尝试实现的目标可以使用document 对象的styleSheets 属性来实现。它比这要复杂一些,因为您需要走到一个相当深的对象链,但仍然适用于包括 Internet Explorer 6 在内的所有主要浏览器。下面是一个概念证明。 CSS 位于 STYLE 标记内,但也可以与外部 CSS 一起使用。我会让你做抽象。

概念证明

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>
<head>
<title></title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="imagetoolbar" content="false">
<meta http-equiv="imagetoolbar" content="no">
<style type="text/css">
.classname {
 color: red;
 font-size: 14px;
}
</style>
<script type="text/javascript">
window.onload = function() {
    document.getElementById("button").onclick = function() {
        var ss = document.styleSheets;

        for (var i=0; i<ss.length; i++) {
            var rules = ss[i].cssRules || ss[i].rules;

            for (var j=0; j<rules.length; j++) {
                if (rules[j].selectorText === ".classname") {
                    rules[j].style.color = "green";
                }
            }
        }
    };
}
</script>
</head>
<body>

<h1 class="classname">Some red text</h1>

<button id="button">Make text green</button>

</body>
</html>

对于您的第二个问题,我没有时间编写解决方案,但它需要像上面一样阅读 CSS 声明并使用 CssRule 对象的 cssText 属性来构建一个字符串,该字符串最终将是使用 Ajax POST 请求发送到服务器。服务器端是你的事。

参考资料:

希望对你有帮助

【讨论】:

  • 感谢 lonut G.Stan 你有多好我从来没有使用过 document.styleSheets 甚至不存在那种东西:S。实际上我想做那种工作coolchaser.com/layout/createrealeditor.com/editor你能告诉我他们是怎么做的吗?
  • @alpav,哦,这是一个错误 :) 我不记得它是如何从我的眼睛中溜走的。
  • 我上面的例子是我从我链接到的文档页面中构思出来的,我想我记得我为什么这样做。我不只是添加一条新规则,而是在现有声明中添加一条新规则。因此,我必须查找每个样式表才能找到该声明。现在,我现在能想到的最好的优化就是以相反的顺序读取styleSheets,并在第一次遇到selectorText 后打破循环。这样,您只需修改一个样式表,即具有最高优先级的样式表。
  • 我不知道为什么,但这个解决方案在 Google Chrome 中不起作用(但奇怪的是它在 Safari 中起作用)。有什么帮助吗?
  • @JesuferVn 为我工作。我已经在答案中使用了确切的代码来测试这个。
【解决方案2】:

最近我需要为 Autocomplete 小部件修复一些 jquery 主题问题。我想更改自动完成小部件的背景颜色。

于是查了一下CSS,发现自动补全类是这样定义的

.ui-autocomplete { position: absolute; cursor: default; }   

所以在我的程序中,我发出以下语句,通过添加背景属性来更改类。请注意,我保留其他属性,否则会破坏现有功能

$("<style type='text/css'> .ui-autocomplete { position: absolute; cursor: default; background:black; color:white} </style>").appendTo("head");

【讨论】:

  • 这个 hack 让我笑了。它从这里得票最高的答案中节省了大量代码。我正在使用它。
【解决方案3】:

只有在以下情况下才应该采用这种方法:

  • 您需要将值设置为 不切实际的东西 枚举(即在 像素)与类名
  • 你想要 将此样式应用于元素 将插入到 DOM 中 未来

有一个 jQuery 插件可以做到这一点:http://plugins.jquery.com/project/jquerycssrule

对于我从事的一个小项目,我提取了基本要素并创建了以下函数:

function addCSSRule(sel, prop, val) {
    for(var i = 0; i < document.styleSheets.length; i++){
        var ss    = document.styleSheets[i];
        var rules = (ss.cssRules || ss.rules);
        var lsel  = sel.toLowerCase();

        for(var i2 = 0, len = rules.length; i2 < len; i2++){
            if(rules[i2].selectorText && (rules[i2].selectorText.toLowerCase() == lsel)){
                if(val != null){
                    rules[i2].style[prop] = val;
                    return;
                }
                else{
                    if(ss.deleteRule){
                        ss.deleteRule(i2);
                    }
                    else if(ss.removeRule){
                        ss.removeRule(i2);
                    }
                    else{
                        rules[i2].style.cssText = '';
                    }
                }
            }
        }
    }

    var ss = document.styleSheets[0] || {};
    if(ss.insertRule) {
        var rules = (ss.cssRules || ss.rules);
        ss.insertRule(sel + '{ ' + prop + ':' + val + '; }', rules.length);
    }
    else if(ss.addRule){
        ss.addRule(sel, prop + ':' + val + ';', 0);
    }
}

【讨论】:

【解决方案4】:

如果我正确理解您的问题,您想通读 CSS 文件,对类进行更改,然后通过保存文件来保留这些更改?

你不能用从客户端运行的 JavaScript/jQuery 来做到这一点;您当然可以更改 DOM 中与 CSS 类匹配的每个单独元素的字体大小 .classname,就像这样

$('.classname').css('font-size','14px');

但客户端 JavaScript 无法从 Web 浏览器访问文件系统,因此您需要其他方式(即服务器端代码)来更改 CSS 文件本身。

【讨论】:

  • 您并没有在此处更改 css 类本身的字体大小,而是向与该类名称匹配的每个 dom 元素添加单独的字体大小样式声明 - 这是一个重要的区别。如果在运行这个 jquery 语句之后,您要构造一个新的 .classname 类的 dom 元素并将其附加到文档中,那么它将没有 font-size 属性。您需要重新运行 jquery 命令来设置新元素的 font-size 属性。
  • @Yetanotherjosh 正确,这对我来说是一个错误的选择。已更新措辞以澄清
【解决方案5】:

你也可以试试 JSS,它对我来说效果很好:https://github.com/Box9/jss

下载 jss.js 并将其包含在您的 HTML 中:

<script type="text/javascript" src="jss.js"></script>

添加新规则(或扩展现有规则):

jss('.special', {
    color: 'red',
    fontSize: '2em',
    padding: '10px'
});

检索现有规则:

jss('.special').get();

返回:

{
    'color': 'red',
    'font-size': '2em',
    'padding-bottom': '10px',
    'padding-left': '10px',
    'padding-right': '10px',
    'padding-top': '10px'
}

删除现有规则:

jss('.special').remove();

【讨论】:

  • @Vladmir 感谢分享,我试试看。
  • 您说“添加”或“扩展”,但您实际上也可以“覆盖”规则吗?我将下载它并尝试一下,如果没有人回答,我会回来回答。
  • 是的,@Jeach,“扩展”实际上意味着“覆盖”。我将它用于 Google Chrome 扩展程序的选项屏幕。当用户定义他们的设置时,他们会覆盖样式表中的信息,因此任何动态添加的元素都会使用新样式。据我所知,使用 jQuery 并没有简单的方法来做到这一点 - 你必须将样式重新应用于新元素,你实际上不能“改变”一个类。 JSS 使用其他一些答案中已经建议的方法简单地修改文档的 css 规则,但方式非常简洁。
  • 不,这对我也不起作用(也尝试过'jQuery.Rules')。请注意,我必须将“z-index”用引号括起来,否则在尝试更改它时会出错。但我认为'jss'和'jQuery.Rules'不起作用的原因是因为实现网页的人在我用AJAX加载的所有页面中引用了CSS以注入正文。所以我不确定这是否是它不起作用的原因,但无论我尝试过什么库,我的规则都不会改变。我需要在某个时候进一步调查,看看我的理论是否是它不起作用的原因!
【解决方案6】:

DOM Level 2 允许直接操作样式表的 css 规则。 例如:

var ss = document.styleSheets[1];  // ref to the first stylesheet
ss.cssRules[0].style.backgroundColor="blue";  // modification of the 1rst rule

有2个接口:

这使得激活/停用样式表、删除规则、添加规则等成为可能... MDM 中的所有详细信息:Using_dynamic_styling_information

【讨论】:

    【解决方案7】:

    您希望通过在服务器上设置几个主题(theme1.css、theme2.css、theme3.css 等)并让用户选择他喜欢的主题来完成。然后,您可以使用用户配置文件将用户选择的主题 (theme2.css) 保存在数据库中。当用户随后显示他的页面时,您在页面顶部包含 theme2.css 而不是主题 default.css。

    这适用于服务器端技术,如 PHP 或 ASP.NET 或任何你喜欢的。当然,您可以使用 javascript 在用户计算机上保存 cookie 以记住他的选择,然后再次使用 javascript 到您通过 cookie 记住的 include the file

    如果您想让用户准确管理适用于设计特定元素的内容(例如标题的颜色、字体等),您可以再次使用服务器端技术(在这种情况下会更好)在我看来)或 javascript 保存诸如 header=blue、font=Arial 之类的内容并使用 jQuery 将存储的内容应用到您的页面。

    希望它能给你一个概述。

    【讨论】:

    • 感谢 ipfavreau 获得了加载不同 css 的第一点,但它将是预定义的。 coolchaser.com/layout/create 想做这种类型的东西或同样改变 myspace 主题。我必须将所有类名保存在数据库和属性中?发送更改 n 检索而不是更改接口?
    • 如果您不介意更改不会永久保留,您可以仅使用 javascript 将更改保存在 cookie 中,但正如我所说,它可能会在数据库中做得更好是的.您可以将所有属性保存在数据库中,然后将它们显示回来,即使不使用 AJAX 重新加载。
    • 太好了,谢谢老兄,我将创建具有所有类名称的数据库表作为表和属性,我也可以在其中更新类规则。我在写吗?
    • 好吧,用简单的评论回答你的架构可能超出了这个答案的范围,你可能想问另一个更关注该特定实现的问题,但基本上,是的,你'将需要一个链接用户、属性和所选值的表。
    【解决方案8】:

    在半相关的注释中,另请参阅我关于更改 LESS 变量的答案,这将导致更新的 CSS 规则。根据您的情况,这可能更有用,因为单个 LESS 变量可以驱动许多 CSS 规则...... https://stackoverflow.com/a/9491074/255961

    【讨论】:

      【解决方案9】:

      不确定是否要更改类属性我来到这里寻找答案,似乎已经有一些答案,至于保存,您可以使用 jquery $.post 方法发送包含更改或 $ 的表单.get 带有 url 编码值,然后使用 PHP fwrite 或 file_put_contents 写入新的 css 文件。在存储任何数据之前,请确保您限制对该功能的访问或确保值符合特定标准。

      【讨论】:

        【解决方案10】:

        对于第一部分,我通常指定一个样式块并使用 jQuery 打开/关闭它。例如:

        <style type="text/css" id="my-style" media="all">
            .classname{color:red; font-size:14px;}
        </style>
        

        然后可以通过设置disabled属性来进行切换,如:

        $('#my-style').prop('disabled', true);
        $('#my-style').prop('disabled', false);
        

        【讨论】:

          【解决方案11】:

          您可以使用 YUI 样式表实用程序。

          http://yuilibrary.com/yui/docs/stylesheet/

          它工作得很好!

          【讨论】:

            【解决方案12】:

            由于应用于头部的样式相互“重载”,它们后期的append() 将使用所有相关元素的样式,除非之前涉及!important

            用于分配 css 内容的函数应该是 text() 而不是 html() 以防止意外注入代码

            var dynamic_css = function(class_name){
              return '.' + class_name + ' {color:red; font-size:14px;}';
            }
            var styles = $('<style type="text/css">');
            styles.text(dynamic_css('my_classname'));
            $('html head').append(styles);
            

            稍后:

            styles.remove();
            

            为样式元素分配一个类以便以后识别它也很有效

            【讨论】:

              【解决方案13】:

              我很确定您无法更改现有样式中的规则。即使萤火虫也不会让你这样做。您可以设置一个元素或一组元素的样式,可以分配和取消分配类,但我认为您不能更改现有的类。为了执行您所要求的操作,您需要维护某种关联数组来记录对现有类的提议更改,然后保存这些更改,您需要上传到服务器,然后服务器可以提供下载到客户端的链接.

              【讨论】:

                【解决方案14】:

                我使用了 jquery 的 addClass :http://api.jquery.com/addClass/ 然后将类设置为我要更改的属性。

                【讨论】:

                  猜你喜欢
                  • 2011-09-01
                  • 2012-04-23
                  • 2012-11-06
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-02-21
                  • 2015-06-26
                  • 2012-08-12
                  相关资源
                  最近更新 更多