Buat aturan / kelas CSS dengan jQuery saat runtime

189

Biasanya saya memiliki file CSS yang memiliki aturan berikut:

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

Bagaimana saya bisa menghindari membuat file CSS statis dengan menambahkan informasi CSS selama tindakan runtime ke tubuh, atau yang serupa? (hanya menggunakan jQuery)

Saya ingin mendefinisikannya sekali tetapi dengan jQuery dan menggunakannya berkali-kali kemudian; itu sebabnya saya tidak ingin menambahkannya setiap kali ke elemen DOM tertentu.

Saya tahu fitur-fitur sederhana ( css("attr1", "value");), tetapi bagaimana saya bisa membuat aturan CSS lengkap yang dapat digunakan kembali?

stephan
sumber

Jawaban:

269

Anda dapat membuat elemen style dan menyisipkannya ke DOM

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

diuji pada Opera10 FF3.5 iE8 iE6

Taras Bulba
sumber
Intinya mandiri. Anda dapat membuatnya secara lokal, dan itu akan berfungsi dengan baik. Tautan langsung ke tautan unduhan: gist.github.com/gists/714352/download
Daniel Ribeiro
Tidak masalah. Terkadang bisa berupa jQuery versi minor bug, atau hanya pengaturan yang salah. Kesepakatan dengan aplikasi js adalah ini: jika mereka tidak bekerja, mereka hanya tidak berfungsi sama sekali. Tidak ada pengampunan.
Daniel Ribeiro
1
Melempar kesalahan ' Panggilan tak terduga ke metode atau akses properti ' untuk saya di IE8. Saya harus mengikuti artikel ini untuk membuatnya berfungsi.
Brandon Boone
6
Hanya ada 31 gaya dalam halaman di IE9- blogs.msdn.com/b/ieinternals/archive/2011/05/14/...
IvanH
1
Jika tidak berhasil. Coba tambahkan gaya ke body. yaitu$("<style>...</style>").appendTo("body");
inDream
118

Secara sederhana

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

Memperhatikan garis belakang? Mereka digunakan untuk bergabung dengan string yang ada di baris baru. Membiarkannya menghasilkan kesalahan.

bogonko
sumber
6
Ini. Seharusnya jawaban yang diterima. Ini sebenarnya menjawab pertanyaan.
Johannes Pille
2
Saya setuju dengan @JohannesPille, ini adalah jawaban yang sebenarnya!
bayu
tidak bekerja di Cordova ios. maukah Anda menyarankan ini?
RamGrg
2
Cukup efisien dan mudah. Setelah aturan baru disuntikkan di header, Anda dapat mengambilnya di mana saja di halaman Anda, termasuk dari PHP.
Brice Coustillas
sama seperti stackoverflow.com/questions/1720320/…
user1742529
17

Anda dapat menerapkan css suatu objek. Jadi Anda bisa mendefinisikan objek Anda di javascript Anda seperti ini:

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

Dan kemudian cukup menerapkannya ke semua elemen yang Anda inginkan

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

Jadi itu bisa digunakan kembali. Apa tujuan Anda melakukan ini?

Yuval Karmi
sumber
22
Saya akan mengatakan ini adalah aturan CSS dan bukan kelas CSS.
hippietrail
17
Jawaban ini menyesatkan. Penanya ingin membuat aturan CSS saat runtime, tidak mengatur gaya elemen tertentu ke deklarasi CSS konstan (dapat digunakan kembali).
Dan Dascalescu
4
Ini tidak sesuai dengan yang mereka minta, tetapi ini adalah solusi yang tepat :) Mengisi dom dengan elemen <style> ekstra memiliki beberapa bau kode yang tidak menyenangkan
Kevin
3
Bagaimana Anda akan menghapus aturan-aturan ini yang diterapkan ketika Anda perlu, itu mungkin dengan solusi lain ...
Vishwanath
@ Kevin - mungkin begitu tetapi ada saat-saat itulah yang Anda butuhkan. misalnya - ketika sebuah elemen sedang dibuat ulang oleh beberapa skrip ajax dan Anda perlu mempertahankan aturan gaya baru.
billynoah
12

Anda dapat menggunakan insertRule jika Anda tidak perlu mendukung IE <9, menurut dottoro . Ada sedikit kode lintas browser di sana juga.

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

Ini adalah plugin jquery yang memungkinkan Anda untuk menyuntikkan CSS:

https://github.com/kajic/jquery-injectCSS

Contoh:

$.injectCSS({
    "#my-window": {
        "position": "fixed",
        "z-index": 102,
        "display": "none",
        "top": "50%",
        "left": "50%"
    }
});
Robert Kajic
sumber
9

Ini bukan sesuatu yang baru dibandingkan dengan beberapa jawaban lain karena menggunakan konsep yang dijelaskan di sini dan di sini , tapi saya ingin memanfaatkan deklarasi gaya JSON:

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

Pemakaian:

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

Saya tidak yakin apakah itu mencakup semua kemampuan CSS, tetapi sejauh ini berfungsi untuk saya. Jika tidak, anggap itu sebagai titik awal untuk kebutuhan Anda sendiri. :)

sjngm
sumber
7

Jika Anda tidak ingin mengubah kode CSS menjadi blok / file CSS, Anda dapat menggunakan jQuery untuk secara dinamis menambahkan CSS ke Elemen HTML, ID, dan Kelas.

$(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);
});
Mike Trpcic
sumber
5
Jawaban ini tidak sesuai dengan yang diminta oleh penanya. Penanya ingin membuat aturan CSS saat runtime, tidak mengatur gaya elemen tertentu ke deklarasi CSS konstan.
Dan Dascalescu
Saya mengerti, tapi ini solusi alternatif, jadi saya berikan.
Mike Trpcic
2
@ MikeTrpcic Masalahnya adalah ada orang lain yang mencari solusi ini juga - untuk menambahkan aturan css ke halaman - dan jawaban Anda tidak menyelesaikannya.
nate
5

Menambahkan aturan khusus berguna jika Anda membuat widget jQuery yang membutuhkan CSS khusus (seperti memperluas kerangka CSS jQueryUI yang ada untuk widget khusus Anda). Solusi ini dibangun berdasarkan jawaban Taras (yang pertama di atas).

Dengan asumsi markup HTML Anda memiliki tombol dengan id "addrule" dan div dengan id "target" yang mengandung beberapa teks:

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

Keuntungan dari pendekatan ini adalah Anda dapat menggunakan kembali variabel cssrules dalam kode Anda untuk menambah atau mengurangi aturan sesuka hati. Jika cssrules tertanam dalam objek persisten seperti widget jQuery, Anda memiliki variabel lokal persisten untuk dikerjakan.

fbloggs
sumber
Ide yang bagus sekali! Saya menggunakannya bersamaan dengan snippet di halaman ini ssdtutorials.com/tutorials/title/jquery-flashing-text.html untuk memungkinkan toggling warna (aslinya hanya akan berganti kelas saja). Terima kasih!
bgmCoder
5

Perhatikan bahwa jQuery().css()tidak mengubah aturan stylesheet, itu hanya mengubah gaya setiap elemen yang cocok.

Sebagai gantinya, inilah fungsi javascript yang saya tulis untuk mengubah aturan stylesheet itu sendiri.

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

Keuntungan:

  • Gaya dapat dihitung dalam <head>skrip sebelum elemen DOM dibuat dan karenanya sebelum rendering dokumen pertama, menghindari render yang menjengkelkan secara visual, kemudian menghitung, lalu merender ulang. Dengan jQuery, Anda harus menunggu elemen DOM untuk dibuat, kemudian gaya ulang dan render ulang.
  • Elemen yang ditambahkan secara dinamis setelah restyle akan secara otomatis menerapkan gaya baru tanpa panggilan tambahan jQuery(newElement).css()

Peringatan:

  • Saya sudah menggunakannya di Chrome dan IE10. Saya pikir mungkin perlu sedikit modifikasi untuk membuatnya bekerja dengan baik pada versi IE yang lebih lama. Secara khusus, versi IE yang lebih lama mungkin tidak s.cssRulesdidefinisikan, sehingga mereka akan kembali ke s.rulesyang memiliki beberapa kekhasan, seperti perilaku aneh / buggy terkait dengan penyeleksi koma-dibatasi, seperti"body, p" . Jika Anda menghindari itu, Anda mungkin ok di versi IE yang lebih lama tanpa modifikasi, tapi saya belum mengujinya.
  • Saat ini penyeleksi harus benar-benar cocok: gunakan huruf kecil, dan berhati-hatilah dengan daftar yang dibatasi koma; urutan harus sesuai dan mereka harus dalam format "first, second"yaitu pembatas adalah koma diikuti oleh karakter spasi.
  • Seseorang mungkin dapat meluangkan waktu tambahan untuk mencoba mendeteksi dan secara cerdas menangani pemilih yang tumpang tindih, seperti yang ada dalam daftar yang dibatasi koma.
  • Orang juga dapat menambahkan dukungan untuk pertanyaan media dan !importantpengubah tanpa terlalu banyak kesulitan.

Jika Anda merasa ingin membuat beberapa perbaikan pada fungsi ini, Anda akan menemukan beberapa dokumen API yang berguna di sini: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet

Craig
sumber
5

Dalam kasus (tidak biasa) di mana Anda ingin dapat sering mengubah gaya secara dinamis - misalnya aplikasi pembuat tema - menambahkan tag <style> atau memanggil CSSStyleSheet.insertRule () akan menghasilkan lembar gaya yang bertambah, yang dapat memiliki kinerja dan desain implikasi debugging.

Pendekatan saya hanya memungkinkan satu aturan per kombo selektor / properti, membersihkan semua yang ada pada pengaturan aturan apa pun. API sederhana dan fleksibel:

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

Pemakaian:

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

clearStyle('body', 'background-color');
addStyle('body', 'color', '#333')
Jason Boyd
sumber
3

Bagaimana jika Anda secara dinamis menulis bagian <script> pada halaman Anda (dengan aturan dinamis Anda) dan kemudian menggunakan jQuerys .addClass (class) untuk menambahkan aturan yang dibuat secara dinamis itu?

Saya belum mencoba ini, hanya menawarkan teori yang mungkin berhasil.

Bryan Denny
sumber
jahitan cara terbaik saat ini. Saya telah menemukan sesuatu jQuery.cssRule tetapi beberapa jenis plugin: - /
stephan
2
$ ("head"). append ($ ("<style type = 'text / css'> ... adalah salah satu cara
stephan
2

Sedikit malas menjawab ini, tetapi artikel berikut dapat membantu: http://www.javascriptkit.com/dhtmltutors/externalcss3.shtml

Juga, coba ketikkan "ubah aturan css" ke google

Tidak yakin apa yang akan terjadi jika Anda mencoba untuk membungkus dokumen.styleSheets [0] dengan jQuery () meskipun Anda bisa mencobanya

James Wiseman
sumber
2

Anda dapat menggunakan plug-in cssRule . Kodenya sederhana:

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

Salah satu komentar sejauh ini bertanya mengapa seseorang ingin melakukan hal seperti itu. Misalnya, membuat gaya untuk daftar di mana setiap item membutuhkan warna latar belakang yang berbeda (mis. Daftar kalender GCal) di mana jumlah kolom tidak diketahui sampai waktu berjalan.

Robert Gowland
sumber
@Aniel, ya itu benar; pernyataan dihapus.
Robert Gowland
tampaknya tidak mendukung aturan seperti ini:div:before{content:'name: ';}
liuyanghejerry
2

Berikut ini adalah pengaturan yang memberikan perintah atas warna dengan objek json ini

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

fungsi ini

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

untuk menghasilkan elemen gaya ini

.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);}
Chris Glasier
sumber
1

jika Anda tidak ingin menetapkan tampilan: tidak ada ke kelas css, pendekatan yang tepat untuk menambahkan gaya, jQuery. Peraturan lakukan pekerjaan itu.

Saya beberapa kasus Anda ingin menerapkan stiles sebelum acara menambahkan konten ajax dan memudar konten setelah menambahkan dan ini dia!

Mattia
sumber
1

Di sini Anda memiliki fungsi untuk mendapatkan definisi penuh dari kelas 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 '';
};
berniecc
sumber
1

Anda dapat menggunakan lib ini disebut cssobj

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

Kapan pun Anda dapat memperbarui aturan Anda seperti ini:

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

Lalu aturan Anda berubah. jQuery bukan lib yang melakukan ini.

James Yang
sumber
0

Saya telah mengacaukan beberapa dari ini baru-baru ini dan saya telah menggunakan dua pendekatan yang berbeda saat memprogram situs iPhone / iPod.

Cara pertama yang saya temui ketika mencari perubahan orientasi sehingga Anda dapat melihat apakah ponsel ini portrait atau landscape, ini adalah cara yang sangat statis tetapi sederhana dan pintar:

Dalam CSS:

#content_right,
#content_normal{
 display:none;
}

Dalam File 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);
}

Dalam PHP / HTML (Impor file JS Anda terlebih dahulu kemudian dalam tag tubuh):

<body onorientationchange="updateOrientation();">

Ini pada dasarnya memilih blok CSS pre set yang berbeda untuk dijalankan tergantung pada hasil yang diberikan kembali dari file JS.

Juga cara yang lebih dinamis yang saya sukai adalah penambahan yang sangat sederhana pada tag skrip atau file JS Anda:

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

Ini berfungsi untuk sebagian besar browser tetapi untuk IE yang terbaik adalah mengambil amunisi dengan sesuatu yang lebih ketat:

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

Atau Anda dapat menggunakan getElementByClass()dan mengubah berbagai item.

Semoga ini membantu!

Abu.

Abu
sumber
-2

Mungkin Anda dapat meletakkan informasi gaya di kelas yang terpisah di file css Anda, misalnya:

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

dan kemudian gunakan jQuery pada titik yang Anda pilih untuk menambahkan classname ini ke elemen?

JorenB
sumber
1
dan Anda tidak ingin menaruh informasi di bagian kepala halaman Anda juga (antara tag gaya)?
JorenB
-2

Anda bisa membuat kelas css bernama sesuatu seperti .fixed-object yang memiliki semua css Anda di dalamnya ...

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

Kemudian di jquery kapan saja Anda menginginkan sesuatu memiliki gaya itu, tambahkan saja kelas itu ke sana ...

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

Itu sepertinya cara termudah untuk melakukannya, kecuali saya salah paham tentang apa yang perlu Anda lakukan.

Pak David dari Lee
sumber
-9

Dengan menggunakan .addClass () di jquery, kita dapat menambahkan gaya secara dinamis ke elemen di halaman. misalnya. kami memiliki gaya

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

Sekarang dalam keadaan jquery siap kita dapat menambahkan css seperti .addClass (myStyle)

Avinash
sumber