在运行时使用jQuery创建CSS规则/类


189

通常我有一个CSS文件,该文件具有以下规则:

#my-window {
    position: fixed;
    z-index: 102;
    display:none;
    top:50%;
    left:50%;
}

如何通过在运行时操作期间将CSS信息添加到正文或类似内容来避免创建这样的静态CSS文件?(仅使用jQuery)

我只想用jQuery定义一次,以后再使用多次;这就是为什么我不想每次都将其添加到特定的DOM元素。

我知道简单的功能(css("attr1", "value");),但是如何创建完整的可重用CSS规则?

Answers:


269

您可以创建样式元素并将其插入DOM

$("<style type='text/css'> .redbold{ color:#f00; font-weight:bold;} </style>").appendTo("head");
$("<div/>").addClass("redbold").text("SOME NEW TEXT").appendTo("body");

在Opera10 FF3.5 iE8 iE6上测试


要点是自给自足的。您可以在本地创建它,并且效果很好。下载链接的直接链接:gist.github.com/gists/714352/download
Daniel Ribeiro 2010年

没问题。有时可能是jQuery的次要版本错误,也可能是错误的设置。与js应用的交易是这样的:如果它们不起作用,那么它们根本就不起作用。没有宽恕。
丹尼尔·里贝罗

1
在IE8中为我引发了“ 对方法或属性访问意外调用 ”错误。我必须按照本文进行操作。
布兰登·布恩


1
如果不起作用。尝试将样式附加到body。即$("<style>...</style>").appendTo("body");
inDream

118

只是

$("<style>")
    .prop("type", "text/css")
    .html("\
    #my-window {\
        position: fixed;\
        z-index: 102;\
        display:none;\
        top:50%;\
        left:50%;\
    }")
    .appendTo("head");

注意到反斜线了吗?它们用于连接换行符。忽略它们会产生错误。


6
这个。应该是公认的答案。它实际上回答了这个问题。
约翰内斯·皮尔

2
我同意@JohannesPille,这是真正的答案!
bayu 2016年

在cordova ios中不工作。您能建议一下吗?
RamGrg

2
非常有效和直接。将新规则注入标头后,您可以在页面中的任何位置(包括PHP在内)检索它。
Brice Coustillas


17

您可以将CSS应用于对象。因此,您可以像这样在javascript中定义对象:

var my_css_class = { backgroundColor : 'blue', color : '#fff' };

然后只需将其应用于您想要的所有元素

$("#myelement").css(my_css_class);

因此,它是可重用的。您会为此目的做什么?


22
我会说这是CSS规则,而不是 CSS类。
hippietrail 2012年

17
这个答案是误导的。询问者想在运行时创建CSS规则,而不是将特定元素的样式设置为恒定(可重用)的CSS声明。
Dan Dascalescu 2012年

4
这并不是他们所要求的,但这是正确的解决方案:)用多余的<style>元素填充dom会有一些讨厌的代码味道
Kevin

3
您将如何删除需要时应用的这些规则,其他解决方案也可能...
Vishwanath 2014年

@Kevin-可能是这样,但是有时候这正是您所需要的。例如-当某个ajax脚本正在重新创建元素时,您需要保留新的样式规则。
Billynoah

12

根据dottoro,如果不需要支持IE <9,则可以使用insertRule。那里也有一些跨浏览器代码。

document.styleSheets[0].insertRule('#my-window {\
    position: fixed;\
    z-index: 102;\
    display:none;\
    top:50%;\
    left:50%;\
}', 0)


9

与其他答案相比,这并不是什么新鲜事物,因为它使用此处此处所述的概念,但我想使用JSON样式的声明:

function addCssRule(rule, css) {
  css = JSON.stringify(css).replace(/"/g, "").replace(/,/g, ";");
  $("<style>").prop("type", "text/css").html(rule + css).appendTo("head");
}

用法:

addCssRule(".friend a, .parent a", {
  color: "green",
  "font-size": "20px"
});

我不确定它是否涵盖CSS的所有功能,但到目前为止,它对我还是有用的。如果不是这样,请考虑将其作为满足您自己需求的起点。:)


7

如果您不想将CSS硬编码为CSS块/文件,则可以使用jQuery将CSS动态添加到HTML元素,ID和类。

$(document).ready(function() {
  //Build your CSS.
  var body_tag_css = {
    "background-color": "#ddd",
    "font-weight": "",
    "color": "#000"
  }
  //Apply your CSS to the body tag.  You can enter any tag here, as
  //well as ID's and Classes.
  $("body").css(body_tag_css);
});

5
这个答案与要求者所要求的不完全相同。询问者想在运行时创建CSS规则,而不是将特定元素的样式设置为恒定的CSS声明。
Dan Dascalescu 2012年

我了解,但这是替代解决方案,因此我提供了它。
Mike Trpcic

2
@MikeTrpcic问题在于,还有其他人也在搜索此解决方案-向页面添加CSS规则-而您的答案并不能解决该问题。
2014年

5

如果您创建需要自定义CSS的jQuery小部件(例如,为特定小部件扩展现有的jQueryUI CSS框架),则添加自定义规则非常有用。该解决方案基于Taras的答案(上面的第一个答案)。

假设您的HTML标记具有一个ID为“ addrule”的按钮和一个ID为“ target”的div,其中包含一些文本:

jQuery代码:

$( "#addrule" ).click(function () { addcssrule($("#target")); });

function addcssrule(target) 
{ 
var cssrules =  $("<style type='text/css'> </style>").appendTo("head");

cssrules.append(".redbold{ color:#f00; font-weight:bold;}"); 
cssrules.append(".newfont {font-family: arial;}"); 
target.addClass("redbold newfont");     
}       

这种方法的优点是您可以在代码中重用可变的cssrules来随意添加或减少规则。如果cssrules嵌入在诸如jQuery小部件之类的持久对象中,则可以使用一个持久局部变量。


好主意!我将其与本页ssdtutorials.com/tutorials/title/jquery-flashing-text.html的片段结合使用,以允许切换颜色(原始颜色只能切换类)。谢谢!
bgmCoder 2013年

5

请注意,jQuery().css()这不会更改样式表规则,而只会更改每个匹配元素的样式。

相反,这是我编写的javascript函数,用于修改样式表规则本身。

    /**
     * Modify an existing stylesheet.
     * - sheetId - the id of the <link> or <style> element that defines the stylesheet to be changed
     * - selector - the id/class/element part of the rule.  e.g. "div", ".sectionTitle", "#chapter2"
     * - property - the CSS attribute to be changed.  e.g. "border", "font-size"
     * - value - the new value for the CSS attribute.  e.g. "2px solid blue", "14px"
     */
    function changeCSS(sheetId, selector, property, value){
        var s = document.getElementById(sheetId).sheet;
        var rules = s.cssRules || s.rules;
        for(var i = rules.length - 1, found = false; i >= 0 && !found; i--){
            var r = rules[i];
            if(r.selectorText == selector){
                r.style.setProperty(property, value);
                found = true;
            }
        }
        if(!found){
            s.insertRule(selector + '{' + property + ':' + value + ';}', rules.length);
        }
    }

优点:

  • 样式可以在 <head>创建DOM元素之前,因此在首次渲染文档之前脚本中,从而避免视觉上令人讨厌的渲染,然后进行计算,然后重新渲染。使用jQuery,您必须等待DOM元素创建,然后重新设置样式并重新呈现它们。
  • 样式更改后动态添加的元素将自动应用新样式,而无需额外调用 jQuery(newElement).css()

注意事项:

  • 我已经在Chrome和IE10上使用过它。我认为可能需要进行一些修改才能使其在旧版本的IE上正常运行。特别是,较旧版本的IE可能尚未s.cssRules定义,因此它们会回落到s.rules某些特殊之处,例如与以逗号分隔的选择器相关的奇怪/笨拙的行为,例如"body, p"。如果您避免这些情况,则在不做任何修改的情况下,使用较旧的IE版本可能没问题,但是我尚未对其进行测试。
  • 当前选择器需要完全匹配:使用小写字母,并注意逗号分隔的列表;订单需要匹配,并且必须采用以下格式:"first, second"即分隔符为逗号,后跟一个空格字符。
  • 可能要花一些额外的时间来尝试检测并智能地处理重叠的选择器,例如逗号分隔列表中的选择器。
  • 也可以添加对媒体查询和!important修饰符的支持而不会带来太多麻烦。

如果您想对该功能进行一些改进,可以在这里找到一些有用的API文档:https : //developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet


5

在(不常见的)情况下,您希望能够经常动态更改样式(例如,主题生成器应用程序),添加<style>标签或调用CSSStyleSheet.insertRule()将导致样式表不断增加,从而可以提高性能和设计调试的含义。

我的方法只允许每个选择器/属性组合使用一条规则,清除设置任何规则时存在的所有规则。该API简单灵活:

function addStyle(selector, rulename, value) {
    var stylesheet = getAppStylesheet();
    var cssRules = stylesheet.cssRules || stylesheet.rules;
    var rule = stylesheet.insertRule(selector + ' { ' + rulename + ':' + value + ';}', cssRules.length);
}

function clearStyle(selector, rulename) {
    var stylesheet = getAppStylesheet();
    var cssRules = stylesheet.cssRules || stylesheet.rules;
    for (var i=0; i<cssRules.length; i++) {
        var rule = cssRules[i];
        if (rule.selectorText == selector && rule.style[0] == rulename) {
            stylesheet.deleteRule(i);
            break;
        }
    }       
}

function addStyles(selector, rules) {
    var stylesheet = getAppStylesheet();
    var cssRules = stylesheet.cssRules || stylesheet.rules;
    for (var prop in rules) {
        addStyle(selector, prop, rules[prop]);
    }
}

function getAppStylesheet() {
    var stylesheet = document.getElementById('my-styles');
    if (!stylesheet) {
        stylesheet = $('<style id="my-styles">').appendTo('head')[0];
    }
    stylesheet = stylesheet.sheet;
    return stylesheet;
}

用法:

addStyles('body', {
    'background-color': 'black',
    color: 'green',
    margin: 'auto'
});

clearStyle('body', 'background-color');
addStyle('body', 'color', '#333')

3

如果您在页面上动态编写了<脚本>部分(带有动态规则),然后使用jQuerys .addClass(class)添加那些动态创建的规则,该怎么办?

我没有尝试过,只是提供了可能有用的理论。


现在缝最好的方法。我已经找到了jQuery.cssRule,但它是某种插件:-/
stephan

2
$(“ head”)。append($(“ <style type ='text / css'> ...是一种方法
Stephan


2

您可以使用cssRule插件。然后,代码很简单:

$.cssRule("#my-window {
    position: fixed;
    z-index: 102;
    display:none;
    top:50%;
    left:50%;
}");

到目前为止,有一条评论询问为什么要这样做。例如,为每个项目需要不同背景色的列表创建样式(例如,GCal的日历列表),直到运行时才知道列数。


@Daniel,是的。声明已删除。
罗伯特·高兰德

似乎不支持这样的规则:div:before{content:'name: ';}
liuyanghejerry

2

这是使用此json对象提供颜色命令的设置

 "colors": {
    "Backlink": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Blazer": ["rgb(240,240,240)"],
    "Body": ["rgb(192,192,192)"],
    "Tags": ["rgb(182,245,245)","rgb(0,0,0)"],
    "Crosslink": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Key": ["rgb(182,245,182)","rgb(0,118,119)"],
    "Link": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Link1": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Link2": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Manager": ["rgb(182,220,182)","rgb(0,118,119)"],
    "Monitor": ["rgb(255,230,225)","rgb(255,80,230)"],
    "Monitor1": ["rgb(255,230,225)","rgb(255,80,230)"],
    "Name": ["rgb(255,255,255)"],
    "Trail": ["rgb(240,240,240)"],
    "Option": ["rgb(240,240,240)","rgb(150,150,150)"]
  }

这个功能

 function colors(fig){
    var html,k,v,entry,
    html = []
    $.each(fig.colors,function(k,v){
        entry  = "." + k ;
        entry += "{ background-color :"+ v[0]+";";
        if(v[1]) entry += " color :"+ v[1]+";";
        entry += "}"
        html.push(entry)
    });
    $("head").append($(document.createElement("style"))
        .html(html.join("\n"))
    )
}

产生这个风格元素

.Backlink{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Blazer{ background-color :rgb(240,240,240);}
.Body{ background-color :rgb(192,192,192);}
.Tags{ background-color :rgb(182,245,245); color :rgb(0,0,0);}
.Crosslink{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Key{ background-color :rgb(182,245,182); color :rgb(0,118,119);}
.Link{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Link1{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Link2{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Manager{ background-color :rgb(182,220,182); color :rgb(0,118,119);}
.Monitor{ background-color :rgb(255,230,225); color :rgb(255,80,230);}
.Monitor1{ background-color :rgb(255,230,225); color :rgb(255,80,230);}
.Name{ background-color :rgb(255,255,255);}
.Trail{ background-color :rgb(240,240,240);}
.Option{ background-color :rgb(240,240,240); color :rgb(150,150,150);}

1

如果您不想将display:none分配给css类,则可以使用正确的方法来添加样式jQuery.Rule。

在某些情况下,您想在ajax内容的append事件之前应用阶梯,并在append之后淡出内容,就是这样!


1

在这里,您可以使用一个函数来获取CSS类的完整定义:

getCSSStyle = function (className) {
   for (var i = 0; i < document.styleSheets.length; i++) {
       var classes = document.styleSheets[i].rules || document.styleSheets[i].cssRules;
       for (var x = 0; x < classes.length; x++) {
           if (classes[x].selectorText  && - 1 != classes[x].selectorText.indexOf(className)) {
               return classes[x].cssText || classes[x].style.cssText;
           }
       }
   }
   return '';
};

1

您可以使用名为 cssobj的库

var result = cssobj({'#my-window': {
  position: 'fixed',
  zIndex: '102',
  display:'none',
  top:'50%',
  left:'50%'
}})

任何时候您都可以像这样更新规则:

result.obj['#my-window'].display = 'block'
result.update()

然后您改变了规则。jQuery不是执行此操作的库。


0

最近,我一直在弄弄其中一些问题,在为iPhone / iPod网站编程时,我使用了两种不同的方法。

寻找方向变化时遇到的第一种方法是,您可以看到手机是纵向还是横向,这是一种非常静态的方法,但又简单又聪明:

在CSS中:

#content_right,
#content_normal{
 display:none;
}

在JS文件中:

function updateOrientation(){
  var contentType = "show_";
  switch(window.orientation){
   case 0:
   contentType += "normal";
   break;

   case -90:
   contentType += "right";
   break; document.getElementById("page_wrapper").setAttribute("class",contentType);
}

在PHP / HTML中(先将JS文件导入,然后在body标签中导入):

<body onorientationchange="updateOrientation();">

基本上,这会根据JS文件返回的结果选择一个不同的预设CSS块来运行。

另外,我更喜欢动态的方法是对脚本标记或JS文件进行非常简单的添加:

document.getelementbyid(id).style.backgroundColor = '#ffffff';

这适用于大多数浏览器,但对于IE而言,最好收紧它的弹药:

var yourID = document.getelementbyid(id); 
 if(yourID.currentstyle) { 
  yourID.style.backgroundColor = "#ffffff";      // for ie :@ 
 } else { 
  yourID.style.setProperty("background-color", "#ffffff");        // everything else :)
 }

或者,您可以使用getElementByClass()和更改一系列项目。

希望这可以帮助!

灰。


-2

也许您可以将样式信息放在css文件中的单独类中,例如:

.specificstyle {
    position: fixed;
    z-index: 102;
    display:none;
    top:50%;
    left:50%;
}

然后在您选择的位置使用jQuery将此类添加到元素?


1
并且您也不想将信息放在页面的头部(在样式标签之间)?
2009年

-2

您可以只创建一个名为.fixed-object的css类,其中包含您的所有css ...

.fixed-object{
    position: fixed;
    z-index: 102;
    display:none;
    top:50%;
    left:50%;
}

然后在jquery中,只要您想要某种具有该样式的东西,只需向其添加该类即可。

$(#my-window).addClass('fixed-object');

这似乎是最简单的方法,除非我误解了您需要做的事情。


-9

通过在jquery中使用.addClass(),我们可以为页面上的元素动态添加样式。例如。我们有风格

.myStyle
{
  width:500px;
  height:300px;
  background-color:red;
 }

现在在jquery的就绪状态下,我们可以添加诸如.addClass(myStyle)之类的CSS。

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.