Mengubah Nilai CSS dengan Javascript

105

Sangat mudah untuk mengatur nilai CSS sebaris dengan javascript. Jika saya ingin mengubah lebarnya dan saya memiliki html seperti ini:

<div style="width: 10px"></div>

Yang perlu saya lakukan adalah:

document.getElementById('id').style.width = value;

Ini akan mengubah nilai lembar gaya sebaris. Biasanya ini bukan masalah, karena gaya sebaris mengganti lembar gaya. Contoh:

<style>
   #tId {
      width: 50%;
   }
</style>

<div id="tId"></div>

Menggunakan Javascript ini:

document.getElementById('tId').style.width = "30%";

Saya mendapatkan yang berikut:

<style>
   #tId {
      width: 50%;
   }
</style>

<div id="tId" style="width: 30%";></div>

Ini adalah masalah, karena saya tidak hanya ingin mengubah nilai sebaris, Jika saya mencari lebarnya sebelum saya mengaturnya, ketika saya memiliki:

<div id="tId"></div>

Nilai yang dikembalikan adalah Null, jadi jika saya memiliki Javascript yang perlu mengetahui lebar sesuatu untuk melakukan beberapa logika (saya menambah lebar sebesar 1%, bukan ke nilai tertentu), mendapatkan kembali Null ketika saya mengharapkan string "50% "tidak benar-benar berfungsi.

Jadi pertanyaan saya: Saya memiliki nilai dalam gaya CSS yang tidak terletak sebaris, bagaimana saya bisa mendapatkan nilai ini? Bagaimana saya bisa mengubah gaya daripada nilai inline, diberi id?

Coltin
sumber
bisakah Anda mengedit posting Anda? ada beberapa kalimat yang tidak lengkap di awal, tidak yakin apa yang Anda cari ...
Jason S
Saya masih sedikit bingung tentang apa yang Anda tanyakan. Apakah Anda meminta 1) untuk mengubah CSS itu sendiri yang akan mengubah semua elemen sekaligus? atau 2) untuk mengubah CSS untuk satu item dalam satu waktu?
Mike
Saya juga bingung dengan pertanyaan sebenarnya. Gaya suatu objek saat ini tidak harus sama dengan atribut 'style' dari tag.
MattJ
Maaf saya akan mengeditnya agar lebih jelas. Saya tidak ingin menyetel CSS sebaris. Saya ingin bisa menambah / mengurangi lebar gaya. Saya akan mengedit dengan contoh lengkap dari apa yang saya cari.
Coltin

Jawaban:

90

Oke, sepertinya Anda ingin mengubah CSS global sehingga secara efektif akan mengubah semua elemen gaya petikular sekaligus. Saya baru-baru ini belajar bagaimana melakukan ini sendiri dari tutorial Shawn Olson . Anda dapat langsung merujuk kodenya di sini .

Berikut ringkasannya:

Anda dapat mengambil stylesheet melalui document.styleSheets. Ini sebenarnya akan mengembalikan array dari semua stylesheet di halaman Anda, tetapi Anda dapat mengetahui yang mana Anda berada melalui document.styleSheets[styleIndex].hrefproperti. Setelah Anda menemukan lembar gaya yang ingin Anda edit, Anda perlu mendapatkan serangkaian aturan. Ini disebut "aturan" di IE dan "cssRules" di sebagian besar browser lain. Cara untuk mengetahui CSSRule tempat Anda berada adalah dengan selectorTextproperti. Kode yang berfungsi terlihat seperti ini:

var cssRuleCode = document.all ? 'rules' : 'cssRules'; //account for IE and FF
var rule = document.styleSheets[styleIndex][cssRuleCode][ruleIndex];
var selector = rule.selectorText;  //maybe '#tId'
var value = rule.value;            //both selectorText and value are settable.

Beri tahu saya cara kerjanya untuk ya, dan beri komentar jika Anda melihat ada kesalahan.

Mike
sumber
1
Mengubah CSS dengan cara ini jauh lebih cepat jika Anda memiliki lebih dari 100 elemen. Katakanlah misalnya, mengubah semua sel di bagian tertentu dari tabel sekaligus.
EdH
5
Saya tidak dapat menemukan rule.valuedi FF 20. rule.styleNamun ada, yang dapat diatur dan berperilaku seperti element.style. Cf. https://developer.mozilla.org/en-US/docs/DOM/CSSStyleRule . Memeriksa rule.type == rule.STYLE_RULEmungkin juga merupakan ide bagus sebelum mengakses rule.selectorText.
Christian Aichinger
1
ITU LUAR BIASA! Saya sedang mengerjakan transisi gambar, dan CSS benar-benar melambat saat Anda mulai meletakkan gambar besar ke dalam 36 URI terpisah untuk mengiris. Ini hanya mengambil satu ton overhead dari skrip saya. Terima kasih!
Jason Maggard
document.styleSheets[styleIndex].cssRules.[ruleIndex].style = {'color':'red', 'background-color':'green'};bekerja untuk saya, terima kasih!
Pavel
43

Silahkan! Tanya saja w3 ( http://www.quirksmode.org/dom/w3c_css.html )! Atau sebenarnya, butuh waktu lima jam ... tapi ini dia!

function css(selector, property, value) {
    for (var i=0; i<document.styleSheets.length;i++) {//Loop through all styles
        //Try add rule
        try { document.styleSheets[i].insertRule(selector+ ' {'+property+':'+value+'}', document.styleSheets[i].cssRules.length);
        } catch(err) {try { document.styleSheets[i].addRule(selector, property+':'+value);} catch(err) {}}//IE
    }
}

Fungsinya sangat mudah digunakan .. contoh:

<div id="box" class="boxes" onclick="css('#box', 'color', 'red')">Click Me!</div>
Or:
<div class="boxes" onmouseover="css('.boxes', 'color', 'green')">Mouseover Me!</div>
Or:
<div class="boxes" onclick="css('body', 'border', '1px solid #3cc')">Click Me!</div>

Oh ..


EDIT: seperti yang dijelaskan @ user21820 dalam jawabannya, mungkin sedikit tidak perlu mengubah semua stylesheet pada halaman. Skrip berikut bekerja dengan IE5.5 serta Google Chrome terbaru, dan hanya menambahkan fungsi css () yang dijelaskan di atas.

(function (scope) {
    // Create a new stylesheet in the bottom
    // of <head>, where the css rules will go
    var style = document.createElement('style');
    document.head.appendChild(style);
    var stylesheet = style.sheet;
    scope.css = function (selector, property, value) {
        // Append the rule (Major browsers)
        try { stylesheet.insertRule(selector+' {'+property+':'+value+'}', stylesheet.cssRules.length);
        } catch(err) {try { stylesheet.addRule(selector, property+':'+value); // (pre IE9)
        } catch(err) {console.log("Couldn't add style");}} // (alien browsers)
    }
})(window);
Leonard Pauli
sumber
Penerapan yang sangat mudah. Terima kasih
Kaleb Anderson
1
Apakah ada alasan untuk memodifikasi setiap stylesheet dibandingkan dengan hanya satu yang baru dibuat seperti dalam jawaban saya?
user21820
Implementasi yang sangat bagus. Kudos to you sir.
Jason Maggard
1
@ user21820, mungkin tidak. Saya rasa saya benar-benar ingin berada di sisi yang aman .. Jawaban akhirnya diperbarui, pujian untuk Anda :)
Leonard Pauli
10

Mengumpulkan kode di jawaban, saya menulis fungsi ini yang tampaknya berjalan dengan baik di FF 25 saya.

function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){
  /* returns the value of the element style of the rule in the stylesheet
  *  If no value is given, reads the value
  *  If value is given, the value is changed and returned
  *  If '' (empty string) is given, erases the value.
  *  The browser will apply the default one
  *
  * string stylesheet: part of the .css name to be recognized, e.g. 'default'
  * string selectorText: css selector, e.g. '#myId', '.myClass', 'thead td'
  * string style: camelCase element style, e.g. 'fontSize'
  * string value optionnal : the new value
  */
  var CCSstyle = undefined, rules;
  for(var m in document.styleSheets){
    if(document.styleSheets[m].href.indexOf(stylesheet) != -1){
     rules = document.styleSheets[m][document.all ? 'rules' : 'cssRules'];
     for(var n in rules){
       if(rules[n].selectorText == selectorText){
         CCSstyle = rules[n].style;
         break;
       }
     }
     break;
    }
  }
  if(value == undefined)
    return CCSstyle[style]
  else
    return CCSstyle[style] = value
}

Ini adalah cara untuk meletakkan nilai di css yang akan digunakan di JS meskipun tidak dipahami oleh browser. misalnya maxHeight untuk tbody dalam tabel yang digulir.

Telepon:

CCSStylesheetRuleStyle('default', "#mydiv", "height");

CCSStylesheetRuleStyle('default', "#mydiv", "color", "#EEE");

FrViPofm
sumber
1
Jika gaya disematkan di halaman HTML, maka document.styleSheets[m].hrefakan menjadi null dan gagal.
JCM
4

Saya tidak tahu mengapa solusi lain melewati seluruh daftar stylesheet untuk dokumen tersebut. Melakukan hal itu membuat entri baru di setiap stylesheet, yang tidak efisien. Sebagai gantinya, kita cukup menambahkan stylesheet baru dan cukup menambahkan aturan CSS yang kita inginkan di sana.

style=document.createElement('style');
document.head.appendChild(style);
stylesheet=style.sheet;
function css(selector,property,value)
{
    try{ stylesheet.insertRule(selector+' {'+property+':'+value+'}',stylesheet.cssRules.length); }
    catch(err){}
}

Perhatikan bahwa kita bisa mengganti bahkan gaya sebaris yang ditetapkan langsung pada elemen dengan menambahkan "! Important" ke nilai properti, kecuali sudah ada deklarasi gaya "! Important" yang lebih spesifik untuk properti itu.

pengguna21820
sumber
1
Lihat developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/… untuk versi yang lebih rumit.
user21820
1
Sangat benar. Pastikan untuk menggunakan .addRule (selector, property + ':' + value) jika .insertRule gagal (untuk dukungan sebelum IE9).
Leonard Pauli
3

Saya tidak memiliki perwakilan yang cukup untuk berkomentar, jadi saya akan memformat jawaban, namun ini hanya demonstrasi dari masalah yang dipermasalahkan.

Tampaknya, ketika gaya elemen didefinisikan dalam stylesheet, gaya tersebut tidak terlihat oleh getElementById ("someElement"). Style

Kode ini menggambarkan masalah ... Kode dari bawah di jsFiddle .

Di Tes 2, pada panggilan pertama, nilai item yang tersisa tidak ditentukan, jadi, apa yang seharusnya menjadi toggle sederhana menjadi kacau. Untuk penggunaan saya, saya akan mendefinisikan nilai gaya penting saya sebaris, tetapi tampaknya itu sebagian mengalahkan tujuan stylesheet.

Ini kode halamannya ...

<html>
  <head>
    <style type="text/css">
      #test2a{
        position: absolute;
        left: 0px;
        width: 50px;
        height: 50px;
        background-color: green;
        border: 4px solid black;
      }
      #test2b{
        position: absolute;
        left: 55px;
        width: 50px;
        height: 50px;
        background-color: yellow;
        margin: 4px;
      }
    </style>
  </head>
  <body>

  <!-- test1 -->
    Swap left positions function with styles defined inline.
    <a href="javascript:test1();">Test 1</a><br>
    <div class="container">
      <div id="test1a" style="position: absolute;left: 0px;width: 50px; height: 50px;background-color: green;border: 4px solid black;"></div>
      <div id="test1b" style="position: absolute;left: 55px;width: 50px; height: 50px;background-color: yellow;margin: 4px;"></div>
    </div>
    <script type="text/javascript">
     function test1(){
       var a = document.getElementById("test1a");
       var b = document.getElementById("test1b");
       alert(a.style.left + " - " + b.style.left);
       a.style.left = (a.style.left == "0px")? "55px" : "0px";
       b.style.left = (b.style.left == "0px")? "55px" : "0px";
     }
    </script>
  <!-- end test 1 -->

  <!-- test2 -->
    <div id="moveDownThePage" style="position: relative;top: 70px;">
    Identical function with styles defined in stylesheet.
    <a href="javascript:test2();">Test 2</a><br>
    <div class="container">
      <div id="test2a"></div>
      <div id="test2b"></div>
    </div>
    </div>
    <script type="text/javascript">
     function test2(){
       var a = document.getElementById("test2a");
       var b = document.getElementById("test2b");
       alert(a.style.left + " - " + b.style.left);
       a.style.left = (a.style.left == "0px")? "55px" : "0px";
       b.style.left = (b.style.left == "0px")? "55px" : "0px";
     }
    </script>
  <!-- end test 2 -->

  </body>
</html>

Saya harap ini membantu menjelaskan masalah ini.

Melewatkan

BentFX
sumber
2

Anda bisa mendapatkan gaya "dihitung" dari elemen apa pun.

IE menggunakan sesuatu yang disebut "currentStyle", Firefox (dan saya menganggap browser "standar yang sesuai" lainnya) menggunakan "defaultView.getComputedStyle".

Anda harus menulis fungsi browser silang untuk melakukan ini, atau menggunakan kerangka kerja Javascript yang bagus seperti prototipe atau jQuery (cari "getStyle" di file javascript prototipe, dan "curCss" di file javascript jquery).

Yang mengatakan jika Anda membutuhkan tinggi atau lebar Anda mungkin harus menggunakan element.offsetHeight dan element.offsetWidth.

Nilai yang dikembalikan adalah Null, jadi jika saya memiliki Javascript yang perlu mengetahui lebar sesuatu untuk melakukan beberapa logika (saya meningkatkan lebar 1%, bukan ke nilai tertentu)

Perhatikan, jika Anda menambahkan gaya sebaris ke elemen yang dipermasalahkan, gaya tersebut dapat bertindak sebagai nilai "default" dan akan dapat dibaca oleh Javascript saat pemuatan laman, karena ini adalah properti gaya sebaris elemen:

<div style="width:50%">....</div>

sumber
0

Inti 32 garis sederhana ini memungkinkan Anda mengidentifikasi lembar gaya tertentu dan mengubah gayanya dengan sangat mudah:

var styleSheet = StyleChanger("my_custom_identifier");
styleSheet.change("darkolivegreen", "blue");
solendil
sumber
0

Saya belum pernah melihat penggunaan praktis ini, tetapi Anda mungkin harus mempertimbangkan stylesheet DOM . Namun, sejujurnya saya pikir itu berlebihan.

Jika Anda hanya ingin mendapatkan lebar dan tinggi elemen, terlepas dari mana dimensinya, cukup gunakan element.offsetWidthdan element.offsetHeight.

Rakesh Pai
sumber
Penggunaan saya: <style> #tid {width: 10%; } </style> <div id = 'tid' onclick = "rise ('tid')"> </div> kenaikan akan memeriksa apakah lebarnya <100%, jika demikian maka akan bertambah 1%. document.getElementById.style.width mengembalikan nol karena tidak ada nilai sebaris. Apakah ada cara yang lebih sederhana daripada DOM Stylesheets?
Coltin
0

Mungkin coba ini:

function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){
  var CCSstyle = undefined, rules;
  for(var m in document.styleSheets){
    if(document.styleSheets[m].href.indexOf(stylesheet) != -1){
     rules = document.styleSheets[m][document.all ? 'rules' : 'cssRules'];
     for(var n in rules){
       if(rules[n].selectorText == selectorText){
         CCSstyle = rules[n].style;
         break;
       }
     }
     break;
    }
  }
  if(value == undefined)
    return CCSstyle[style]
  else
    return CCSstyle[style] = value
}
Shaq
sumber