การเปลี่ยนค่า CSS ด้วย Javascript


104

ง่ายต่อการตั้งค่า CSS แบบอินไลน์ด้วยจาวาสคริปต์ หากฉันต้องการเปลี่ยนความกว้างและมี html ดังนี้:

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

สิ่งที่ฉันต้องทำคือ:

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

มันจะเปลี่ยนค่าสไตล์ชีตแบบอินไลน์ โดยปกตินี่ไม่ใช่ปัญหาเนื่องจากสไตล์อินไลน์จะแทนที่สไตล์ชีต ตัวอย่าง:

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

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

การใช้ Javascript นี้:

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

ฉันได้รับสิ่งต่อไปนี้:

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

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

นี่เป็นปัญหาเพราะไม่เพียง แต่ฉันไม่ต้องการเปลี่ยนค่าอินไลน์เท่านั้นหากฉันมองหาความกว้างก่อนที่จะตั้งค่าเมื่อฉันมี:

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

ค่าที่ส่งคืนเป็น Null ดังนั้นหากฉันมี Javascript ที่ต้องการทราบความกว้างของบางสิ่งเพื่อทำตรรกะบางอย่าง (ฉันเพิ่มความกว้างขึ้น 1% ไม่ใช่ค่าเฉพาะ) จะกลับเป็น Null เมื่อฉันคาดหวังสตริง "50% "ใช้ไม่ได้จริงๆ.

ดังนั้นคำถามของฉัน: ฉันมีค่าในสไตล์ CSS ที่ไม่ได้อยู่ในบรรทัดฉันจะรับค่าเหล่านี้ได้อย่างไร ฉันจะแก้ไขสไตล์แทนค่าแบบอินไลน์โดยให้ id ได้อย่างไร


คุณสามารถแก้ไขโพสต์ของคุณได้ไหม มีบางประโยคที่ไม่สมบูรณ์ในตอนต้นไม่แน่ใจว่าคุณกำลังมองหาอะไร ...
Jason S

ฉันยังสับสนเล็กน้อยเกี่ยวกับสิ่งที่คุณกำลังถาม คุณกำลังขอให้ 1) เปลี่ยน CSS เองซึ่งจะเปลี่ยนองค์ประกอบทั้งหมดในครั้งเดียวหรือไม่? หรือ 2) เพื่อเปลี่ยน CSS ทีละรายการ?
Mike

ฉันยังสับสนกับคำถามที่แท้จริง รูปแบบของวัตถุในปัจจุบันไม่จำเป็นต้องเหมือนกับแอตทริบิวต์ "style" ของแท็ก
MattJ

ขออภัยฉันจะแก้ไขให้ชัดเจนยิ่งขึ้น ฉันไม่ต้องการตั้งค่า CSS แบบอินไลน์ ฉันต้องการเพิ่ม / ลดความกว้างของสไตล์ ฉันจะแก้ไขด้วยตัวอย่างเต็มรูปแบบของสิ่งที่ฉันกำลังมองหา
Coltin

คำตอบ:


89

โอเคดูเหมือนว่าคุณต้องการเปลี่ยน CSS ทั่วโลกซึ่งจะเปลี่ยนองค์ประกอบทั้งหมดของรูปแบบ peticular พร้อมกันอย่างมีประสิทธิภาพ ฉันได้เรียนรู้เมื่อเร็ว ๆ นี้ว่าการทำเช่นนี้ตัวเองจากShawn โอลสันกวดวิชา คุณโดยตรงสามารถอ้างอิงรหัสของเขาที่นี่

นี่คือบทสรุป:

คุณสามารถดึงสไตล์ชีทได้ทางdocument.styleSheets. สิ่งนี้จะส่งคืนอาร์เรย์ของสไตล์ชีททั้งหมดในเพจของคุณ แต่คุณสามารถบอกได้ว่าคุณใช้สไตล์ไหนผ่านdocument.styleSheets[styleIndex].hrefคุณสมบัติ เมื่อคุณพบสไตล์ชีตที่ต้องการแก้ไขแล้วคุณจะต้องได้รับอาร์เรย์ของกฎ สิ่งนี้เรียกว่า "กฎ" ใน IE และ "cssRules" ในเบราว์เซอร์อื่น ๆ ส่วนใหญ่ วิธีที่จะบอกได้ว่าคุณใช้CSSRuleอะไรอยู่ในselectorTextคุณสมบัติ รหัสการทำงานมีลักษณะดังนี้:

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.

แจ้งให้เราทราบวิธีการทำงานของคุณและโปรดแสดงความคิดเห็นหากคุณพบข้อผิดพลาดใด ๆ


1
การเปลี่ยน CSS ด้วยวิธีนี้จะเร็วกว่ามากหากคุณมีองค์ประกอบมากกว่า 100 รายการ ตัวอย่างเช่นการเปลี่ยนเซลล์ทั้งหมดในส่วนหนึ่งของตารางพร้อมกัน
EdH

5
ฉันไม่สามารถหาrule.valueใน FF 20. มีแต่ที่เป็นตัวอย่างไฟล์และพฤติกรรมเช่นrule.style element.styleCf. https://developer.mozilla.org/en-US/docs/DOM/CSSStyleRule กำลังตรวจสอบยังอาจจะเป็นความคิดที่ดีก่อนที่จะเข้าถึงrule.type == rule.STYLE_RULE rule.selectorText
Christian Aichinger

1
ที่ยอดเยี่ยม! ฉันกำลังทำงานกับการเปลี่ยนภาพและ CSS จะช้าลงอย่างมากเมื่อคุณเริ่มใส่ภาพขนาดใหญ่ลงใน URI แยกต่างหาก 36 รายการสำหรับการแบ่งส่วน นี่ทำให้สคริปต์ของฉันมีค่าใช้จ่ายมากเกินไป ขอบคุณ!
Jason Maggard

1
ในปี 2559 ใช้สิ่งนี้: developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/…
the_web

document.styleSheets[styleIndex].cssRules.[ruleIndex].style = {'color':'red', 'background-color':'green'};ทำงานให้ฉันขอบคุณ!
Pavel

43

กรุณา! แค่ถาม w3 ( http://www.quirksmode.org/dom/w3c_css.html )! หรือจริงๆแล้วฉันใช้เวลาห้าชั่วโมง ... แต่นี่ไง!

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

ฟังก์ชั่นใช้งานง่ายมาก .. ตัวอย่าง:

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

โอ้ ..


แก้ไข:ตามที่ @ user21820 อธิบายไว้ในคำตอบการเปลี่ยนสไตล์ชีททั้งหมดในเพจอาจไม่จำเป็นเล็กน้อย สคริปต์ต่อไปนี้ใช้งานได้กับ IE5.5 และ Google Chrome รุ่นล่าสุดและเพิ่มเฉพาะฟังก์ชัน css () ที่อธิบายไว้ข้างต้น

(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);

ใช้งานง่ายอย่างจริงจัง ขอบคุณ
Kaleb Anderson

1
มีเหตุผลในการปรับเปลี่ยนสไตล์ชีตทุกรายการเมื่อเทียบกับสไตล์ชีทที่สร้างขึ้นใหม่เพียงรายการเดียวในคำตอบของฉัน
user21820

การใช้งานที่ดีมาก ขอชื่นชมคุณครับ
Jason Maggard

1
@ user21820 คงไม่ใช่ ฉันเดาว่าฉันอยากจะอยู่อย่างปลอดภัยจริงๆ .. คำตอบอัปเดตในที่สุดขอชื่นชมคุณ :)
Leonard Pauli

10

เมื่อรวบรวมรหัสในคำตอบฉันเขียนฟังก์ชันนี้ซึ่งดูเหมือนว่าจะทำงานได้ดีใน FF 25 ของฉัน

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
}

นี่เป็นวิธีใส่ค่าใน css ที่จะใช้ใน JS แม้ว่าเบราว์เซอร์จะไม่เข้าใจก็ตาม เช่น maxHeight สำหรับ tbody ในตารางเลื่อน

โทร :

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

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


1
หากสไตล์ฝังอยู่ในหน้า HTML ก็document.styleSheets[m].hrefจะเป็นโมฆะและล้มเหลว
JCM

4

ฉันไม่รู้ว่าทำไมวิธีแก้ปัญหาอื่น ๆ ถึงใช้รายการสไตล์ชีททั้งหมดสำหรับเอกสาร เพื่อสร้างรายการใหม่ในแต่ละสไตล์ชีตซึ่งไม่มีประสิทธิภาพ แต่เราสามารถต่อท้ายสไตล์ชีตใหม่และเพิ่มกฎ CSS ที่ต้องการได้ที่นั่น

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

โปรดทราบว่าเราสามารถลบล้างได้แม้กระทั่งรูปแบบอินไลน์ที่กำหนดไว้บนองค์ประกอบโดยตรงโดยการเพิ่ม "! important" ให้กับค่าของคุณสมบัติเว้นแต่จะมีการประกาศรูปแบบ "! important" ที่เฉพาะเจาะจงมากขึ้นสำหรับคุณสมบัตินั้น


1
โปรดดูdeveloper.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/…สำหรับเวอร์ชันที่ซับซ้อนมากขึ้น
user21820

1
จริงแท้แน่นอน. อย่าลืมใช้. addRule (ตัวเลือกคุณสมบัติ + ':' + ค่า) ถ้า. insertRule ล้มเหลว (สำหรับการรองรับ IE9 ก่อน)
Leonard Pauli

3

ฉันไม่มีตัวแทนเพียงพอที่จะแสดงความคิดเห็นดังนั้นฉันจะจัดรูปแบบคำตอบ แต่เป็นเพียงการสาธิตปัญหาที่เป็นปัญหาเท่านั้น

ดูเหมือนว่าเมื่อมีการกำหนดสไตล์องค์ประกอบในสไตล์ชีตพวกเขาจะมองไม่เห็น getElementById ("someElement") style

รหัสนี้แสดงให้เห็นถึงปัญหา ... รหัสจากด้านล่างบน jsFiddle

ในการทดสอบที่ 2 ในการโทรครั้งแรกค่าที่เหลือของรายการจะไม่ถูกกำหนดดังนั้นสิ่งที่ควรจะเป็นการสลับแบบธรรมดาจึงทำให้เกิดความสับสน สำหรับการใช้งานของฉันฉันจะกำหนดค่าสไตล์ที่สำคัญของฉันแบบอินไลน์ แต่ดูเหมือนว่าจะเอาชนะจุดประสงค์ของสไตล์ชีทไปบางส่วน

นี่คือรหัสหน้า ...

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

ฉันหวังว่านี่จะช่วยให้ประเด็นนี้กระจ่างขึ้น

ข้าม


2

คุณสามารถรับรูปแบบ "คำนวณ" ขององค์ประกอบใดก็ได้

IE ใช้สิ่งที่เรียกว่า "currentStyle", Firefox (และฉันถือว่าเบราว์เซอร์ "ตามมาตรฐาน" อื่น ๆ ) ใช้ "defaultView.getComputedStyle"

คุณจะต้องเขียนฟังก์ชันข้ามเบราว์เซอร์เพื่อทำสิ่งนี้หรือใช้เฟรมเวิร์ก Javascript ที่ดีเช่นต้นแบบหรือ jQuery (ค้นหา "getStyle" ในไฟล์จาวาสคริปต์ต้นแบบและ "curCss" ในไฟล์จาวาสคริปต์ jquery)

ที่กล่าวว่าหากคุณต้องการความสูงหรือความกว้างคุณควรใช้ element.offsetHeight และ element.offsetWidth

ค่าที่ส่งคืนเป็น Null ดังนั้นหากฉันมี Javascript ที่ต้องการทราบความกว้างของบางสิ่งเพื่อทำตรรกะบางอย่าง (ฉันเพิ่มความกว้างขึ้น 1% ไม่ใช่ค่าเฉพาะ)

โปรดทราบว่าหากคุณเพิ่มสไตล์อินไลน์ให้กับองค์ประกอบที่เป็นปัญหาก็สามารถทำหน้าที่เป็นค่า "เริ่มต้น" และ Javascript จะอ่านได้ในการโหลดหน้าเนื่องจากเป็นคุณสมบัติสไตล์อินไลน์ขององค์ประกอบ:

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


0

ผมไม่เคยเห็นการใช้งานจริงใด ๆ นี้ แต่คุณอาจควรพิจารณาstylesheets DOM อย่างไรก็ตามฉันคิดว่ามันเกินความจริง

หากคุณเพียงแค่ต้องการที่จะได้รับความกว้างและความสูงขององค์ประกอบโดยไม่คำนึงถึงมิติที่จะถูกนำมาใช้จากเพียงแค่ใช้และelement.offsetWidthelement.offsetHeight


การใช้งานของฉัน: <style> #tid {width: 10%; } </style> <div id = 'tid' onclick = "เพิ่ม ('tid')"> </div> เพิ่มขึ้นจะตรวจสอบว่าความกว้าง <100% หรือไม่ถ้าเป็นเช่นนั้นจะเพิ่มขึ้น 1% document.getElementById.style.width ส่งคืนค่า null เนื่องจากไม่มีค่าแบบอินไลน์ มีวิธีที่ง่ายกว่า DOM Stylesheets หรือไม่?
Coltin

0

อาจลองสิ่งนี้:

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
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.