Çalışma zamanında jQuery ile bir CSS kuralı / sınıfı oluşturma


189

Genellikle aşağıdaki kuralı olan bir CSS dosyası var:

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

Gövdeye çalışma zamanı eylemleri sırasında CSS bilgilerini veya benzer bir şeyi ekleyerek böyle bir statik CSS dosyası oluşturmaktan nasıl kaçınabilirim? (sadece jQuery kullanarak)

Bir kez ama jQuery ile tanımlamak ve daha sonra birçok kez kullanmak istiyorum; bu yüzden her seferinde belirli DOM öğelerine eklemek istemiyorum.

Basit özellikleri biliyorum ( css("attr1", "value");), ancak nasıl tam bir yeniden kullanılabilir CSS kuralı oluşturabilirim?

Yanıtlar:


269

Stil öğesi oluşturabilir ve bunu DOM'a ekleyebilirsiniz

$("<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 üzerinde test edilmiştir


Gist kendi kendine yeterlidir. Yerel olarak oluşturabilirsiniz ve iyi çalışır. İndirme bağlantısına doğrudan bağlantı: gist.github.com/gists/714352/download
Daniel Ribeiro

Sorun değil. Bazen jQuery küçük sürüm hatası veya sadece yanlış bir kurulum olabilir. Js apps ile anlaşma şudur: eğer işe yaramazlarsa, hiç işe yaramazlar. Af yok.
Daniel Ribeiro

1
Bir 'Atar yöntem veya özellik erişim için Beklenmeyen çağrı IE8 benim için hata'. Çalışması için bu makaleyi takip etmek zorunda kaldım .
Brandon Boone


1
Eğer işe yaramazsa. İçin stil eklemeyi deneyin body. ie$("<style>...</style>").appendTo("body");
inDream

118

basitçe

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

Arka eğik çizgileri fark ettiniz mi? Yeni satırlardaki dizeleri birleştirmek için kullanılırlar. Onları dışarıda bırakmak bir hataya neden olur.


6
Bu. Kabul edilen cevap olmalı. Aslında soruyu cevaplıyor.
Johannes Pille

2
@JohannesPille ile hemfikirim, bu gerçek cevap!
bayu

cordova ios'ta çalışmıyor. lütfen bunu önerecek misin
RamGrg

2
Oldukça verimli ve anlaşılır. Yeni kural başlığa enjekte edildikten sonra, PHP'den de dahil olmak üzere sayfanızın herhangi bir yerine erişebilirsiniz.
Brice Coustillas


17

css ve bir nesneye uygulayabilirsiniz. Böylece nesnenizi javascriptinizde şu şekilde tanımlayabilirsiniz:

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

Ve sonra sadece istediğiniz tüm öğelere uygulayın

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

Yani yeniden kullanılabilir. Bunu ne amaçla yapardınız?


22
Bunun bir CSS kuralı değil, bir CSS sınıfı olduğunu söyleyebilirim .
hippietrail

17
Bu cevap yanıltıcı. Asker, belirli bir öğenin stilini sabit (yeniden kullanılabilir) bir CSS bildirimine ayarlamak yerine çalışma zamanında bir CSS kuralı oluşturmak istedi.
Dan Dascalescu

4
İstedikleri tam olarak değil, ama doğru çözüm :) Domu ekstra <style> elemanları ile doldurmanın bazı kötü kod kokusu var
Kevin

3
İhtiyacınız olduğunda uygulanan bu kuralları nasıl kaldıracaksınız, bu diğer çözümlerle mümkün ...
Vishwanath

@Kevin - öyle olabilir, ancak tam da ihtiyacınız olan zamanlar vardır. örneğin - bir öğe bazı ajax betiği tarafından yeniden oluşturulduğunda ve yeni bir stil kuralı sürdürmeniz gerektiğinde.
billynoah

12

Sen kullanabilirsiniz insertRule IE <9 desteklemek için gerekmiyorsa göre, dottoro . Orada da çapraz tarayıcı kodu var.

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


9

Bu, burada ve burada açıklanan kavramı kullandığından diğer cevaplara kıyasla yeni bir şey değil , ancak JSON tarzı bildirimi kullanmak istedim:

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

Kullanımı:

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

CSS'in tüm yeteneklerini kapsadığından emin değilim, ancak şu ana kadar benim için çalışıyor. Değilse, kendi ihtiyaçlarınız için bir başlangıç ​​noktası olarak düşünün. :)


7

CSS'yi bir CSS bloğuna / dosyasına kodlamak istemiyorsanız, HTML Öğelerine, Kimliklere ve Sınıflara dinamik olarak CSS eklemek için jQuery kullanabilirsiniz.

$(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
Bu cevap askerin istediği gibi değil. Asker, belirli bir öğenin stilini sabit bir CSS bildirimine ayarlamak yerine çalışma zamanında bir CSS kuralı oluşturmak istedi.
Dan Dascalescu

Anlıyorum, ama bu alternatif bir çözüm, bu yüzden sağladım.
Mike Trpcic

2
@MikeTrpcic Sorun, bu çözümü arayan başkalarının da var olması - bir sayfaya css kuralları eklemek - ve cevabınız bunu çözmüyor.
nate

5

Özel CSS gerektiren bir jQuery widget'ı oluşturuyorsanız (belirli widget'ınız için mevcut jQueryUI CSS çerçevesini genişletmek gibi) özel kurallar eklemek yararlıdır. Bu çözüm Taras'ın cevabı üzerine kuruludur (yukarıdaki ilk cevap).

HTML işaretlemenizin "addrule" kimliğine sahip bir düğmesi ve bazı metin içeren "target" kimliğine sahip bir div düğmesi olduğunu varsayarsak:

jQuery kodu:

$( "#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");     
}       

Bu yaklaşımın avantajı, kodunuzdaki değişken cssrule'leri istediğiniz zaman kural eklemek veya çıkarmak için yeniden kullanabilmenizdir. Cssrules jQuery widget'ı gibi kalıcı bir nesneye gömülmüşse, üzerinde çalışmak için kalıcı bir yerel değişkeniniz vardır.


Ne güzel bir fikir! Bir renk geçişine izin vermek için bu sayfada ssdtutorials.com/tutorials/title/jquery-flashing-text.html snippet ile birlikte kullandım (orijinal yalnızca bir sınıfı değiştirir). Teşekkürler!
bgmCoder

5

jQuery().css()Stil sayfası kurallarını değiştirmediğini, yalnızca eşleşen her öğenin stilini değiştirdiğini unutmayın .

Bunun yerine, burada stil sayfası kurallarını değiştirmek için yazdığım bir javascript işlevi.

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

Avantajları:

  • Stiller bir hesaplanabilir <head> , DOM öğeleri oluşturulmadan önce ve bu nedenle belgenin ilk oluşturulmasından önce görsel olarak can sıkıcı bir işlemden kaçınarak hesaplanır, sonra yeniden hesaplanır ve yeniden oluşturulur. JQuery ile DOM öğelerinin oluşturulmasını beklemeniz, ardından yeniden stil vermeniz ve yeniden oluşturmanız gerekir.
  • Restyle'dan sonra dinamik olarak eklenen öğelere, yeni stiller otomatik olarak ek bir çağrı yapılmadan uygulanır. jQuery(newElement).css()

Uyarılar:

  • Chrome ve IE10'da kullandım. Ben IE eski sürümlerinde iyi çalışması için küçük bir değişiklik gerekebilir düşünüyorum. Özellikle, IE'nin daha eski sürümleri s.cssRulestanımlanmamış olabilir , bu nedenle s.rules, virgülle ayrılmış seçicilerle ilgili garip / buggy davranışı gibi bazı özellikleri olan geri düşeceklerdir "body, p". Bunlardan kaçınırsanız, eski IE sürümlerinde değişiklik yapmadan iyi olabilirsiniz, ancak henüz test etmedim.
  • Şu anda seçicilerin tam olarak eşleşmesi gerekiyor: küçük harf kullanın ve virgülle ayrılmış listelere dikkat edin; siparişin eşleşmesi gerekir ve bunlar formatta olmalıdır, "first, second"yani sınırlayıcı bir virgül ve onu izleyen bir boşluk karakteri olmalıdır.
  • Büyük olasılıkla, virgülle ayrılmış listelerdeki gibi çakışan seçicileri algılamaya ve akıllıca işlemeye çalışmak için biraz zaman harcayabilir.
  • Ayrıca medya sorguları ve !importantdeğiştirici için çok fazla sorun olmadan destek eklenebilir .

Bu işlevde bazı iyileştirmeler yapmak istiyorsanız, burada bazı yararlı API belgeleri bulacaksınız: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet


5

Stilleri sık sık dinamik olarak değiştirmek istediğiniz (olağandışı) durumlarda - örneğin bir tema oluşturucu uygulaması - <style> etiketleri eklemek veya CSSStyleSheet.insertRule () öğesini çağırmak, performans ve tasarıma sahip olabilecek büyüyen bir stil sayfasına neden olur. hata ayıklama sonuçları.

Yaklaşımım, seçici / özellik birleşimi başına yalnızca tek bir kurala izin vererek, herhangi bir kuralı belirlerken varolanları temizler. API basit ve esnektir:

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

Kullanımı:

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

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

3

Sayfanıza dinamik olarak bir <komut dosyası> bölümü yazdıysanız (dinamik kurallarınızla) ve ardından dinamik olarak oluşturulan bu kuralları eklemek için jQuerys .addClass (sınıf) kullandıysanız?

Bunu denemedim, sadece işe yarayabilecek bir teori önerdim.


şu anda en iyi yol dikişleri. i bir şey buldum jQuery.cssRule ama bir tür eklenti: - /
stephan

2
$ ("head"). append ($ ("<style type = 'text / css'> ... tek yön
stephan


2

Bir cssRule eklentisi kullanabilirsiniz . Kod basitti:

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

Şimdiye kadar yapılan yorumlardan biri neden böyle bir şey yapmak isteyeceğini sordu. Örneğin, her öğenin sütun sayısının çalışma süresine kadar bilinmediği ayrı bir arka plan rengine (örn. GCal'ın takvimler listesi) ihtiyaç duyduğu bir liste için stiller oluşturmak.


@ Daniel, evet öyle; ifade kaldırıldı.
Robert Gowland

gibi kuralı desteklemiyor gibi görünüyor:div:before{content:'name: ';}
liuyanghejerry

2

İşte bu json nesnesiyle renkler üzerinde komut veren bir kurulum

 "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)"]
  }

bu fonksiyon

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

bu stil öğesini üretmek için

.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

bir görüntü atamak istemiyorsanız: hiçbiri bir css sınıfına, stile eklemek için doğru yaklaşım, jQuery.Rule işi yapın.

Ben ajax içeriğinin append olayı önce stiles uygulamak istiyorum ve append sonra içerik solmaya ve bu kadar!


1

Burada bir CSS sınıfının tam tanımını almak için bir fonksiyonunuz var:

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 adlı bu kütüphaneyi kullanabilirsiniz

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

Kurallarınızı istediğiniz zaman güncelleyebilirsiniz:

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

Sonra kural değişti. jQuery bunu yapan lib değildir.


0

Son zamanlarda bunlardan bazılarını karıştırıyorum ve bir iPhone / iPod sitesini programlarken iki farklı yaklaşım kullandım.

Oryantasyon değişiklikleri ararken ilk karşılaştığım yol, böylece telefonun portre mi yoksa manzara mı olduğunu görebiliyorsunuz, bu çok statik bir yol ama basit ve akıllı:

CSS'de:

#content_right,
#content_normal{
 display:none;
}

JS Dosyasında:

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'de (Önce JS dosyanızı sonra gövde etiketinde içe aktarın):

<body onorientationchange="updateOrientation();">

Bu temelde JS dosyasından verilen sonuca bağlı olarak çalışacak farklı bir ön ayarlı CSS bloğu seçer.

Ayrıca tercih ettiğim daha dinamik bir yol, bir komut dosyası etiketine veya JS dosyanıza çok basit bir eklentiydi:

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

Bu, çoğu tarayıcı için çalışır, ancak IE için, daha sıkı bir şeyle mühimmatını çıkarmak en iyisidir:

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

Veya getElementByClass()bir dizi öğeyi kullanabilir ve değiştirebilirsiniz.

Bu yardımcı olur umarım!

Kül.


-2

Belki de stil bilgilerini css dosyanızda ayrı bir sınıfa koyabilirsiniz, örneğin:

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

ve sonra bu sınıf adını öğeye eklemek için seçtiğiniz noktada jQuery?


1
ve bilgileri sayfanızın baş bölümüne (stil etiketleri arasında) da koymak istemiyor musunuz?
JorenB

-2

İçinde tüm css'lerinizin bulunduğu .fixed-object gibi bir şey denilen bir css sınıfı yapabilirsiniz ...

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

Sonra jquery her zaman bu tarz bir şey olmasını istediğinizde sadece o sınıfı ekleyin ...

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

Yapman gereken şeyi yanlış anlamadım, bunu yapmanın en kolay yolu gibi görünüyor.


-9

Jquery'de .addClass () kullanarak sayfadaki öğelere dinamik olarak stil ekleyebiliriz. Örneğin. tarzımız var

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

Şimdi jquery'nin hazır durumunda .addClass (myStyle) gibi css ekleyebiliriz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.