webentwicklung-frage-antwort-db.com.de

CSS-Klasseneigenschaftswerte im Handumdrehen mit JavaScript/jQuery ändern

Ich bin in eine einzigartige Situation geraten, für die ich bisher keine Lösung finden konnte: Dynamisches Zuweisen eines Werts zu einem CSS-Stil. Ich weiß, wie man jQuery verwendet, um einem Element Breite, Höhe usw. zuzuweisen. Ich versuche jedoch, den im Stylesheet definierten Wert so zu ändern, dass der dynamisch erstellte Wert mehreren Elementen zugewiesen werden kann. 

Was ich gerade baue, ist eine Diashow mit Bildern, die den gesamten Darstellungsbereich einnehmen, die Breite, Höhe und linken Eigenschaften des Bilds bei der Größenänderung neu berechnen, sodass das Bild immer zentriert ist und die Breite über die Höhe zieht, außer wenn der Darstellungsbereich höher ist als er ist Breit (durch Ändern der Größe wird die Seite nicht neu geladen, es wird lediglich eine Funktion zum Ändern der Größe des Bildes ausgelöst). 

Es ist mir gelungen, das Bild an einem Bild zu bearbeiten, und jetzt versuche ich, die beste Methode zu bestimmen, um diese Eigenschaftswerte allen Bildern in der Diashow zuzuweisen, ohne diese drei Dinge für jedes Bild einzeln angeben zu müssen. 

Meine Frage:

Können die Werte von Eigenschaften in einer Klasse sofort geändert werden? Ich bin mir sicher, dass die Antwort da draußen ist. Ich verwende wahrscheinlich nicht die korrekte Terminologie in meinen Suchen. Ich hoffe, ich habe das Problem gut beschrieben. TIA.

50
JPN

Im Gegensatz zu einigen Antworten ist das Editieren des Stylesheets mit Javascript nicht nur möglich, sondern auch eine höhere Leistung. Wenn Sie einfach $('.myclass').css('color: red') ausführen, wird jedes Element, das mit dem Selektor übereinstimmt, durchlaufen und das style-Attribut individuell eingestellt. Das ist wirklich ineffizient und wenn Sie Hunderte von Elementen haben, wird es Probleme verursachen.

Das Ändern von Klassen für die Elemente ist eine bessere Idee, aber Sie haben immer noch das gleiche Problem, dass Sie ein Attribut für N Elemente ändern, was eine große Anzahl sein kann. Eine bessere Lösung könnte sein, die Klasse eines einzelnen übergeordneten Elements oder einer kleinen Anzahl von übergeordneten Elementen zu ändern und dann die Zielelemente mit "Cascade" in css zu treffen. Dies dient in den meisten Situationen, aber nicht allen.

Manchmal müssen Sie das CSS vieler Elemente in etwas Dynamisches umwandeln, oder es gibt keine gute Möglichkeit, dies zu tun, indem Sie eine kleine Anzahl von Eltern treffen. Das Ändern des Stylesheets selbst oder das Hinzufügen eines kleinen neuen, um die vorhandenen CSS zu überschreiben, ist eine äußerst effiziente Möglichkeit, die Anzeige von Elementen zu ändern. Sie interagieren nur mit dem DOM an einer Stelle, und der Browser kann diese Änderungen sehr effizient implementieren.

jss ist eine Bibliothek, die das direkte Bearbeiten des Stylesheets von Javascript aus einfacher macht.

28
user748221

Demo , IE Demo

Sie können die folgende Funktion verwenden:

function setStyle(cssText) {
    var sheet = document.createElement('style');
    sheet.type = 'text/css';
    /* Optional */ window.customSheet = sheet;
    (document.head || document.getElementsByTagName('head')[0]).appendChild(sheet);
    return (setStyle = function(cssText, node) {
        if(!node || node.parentNode !== sheet)
            return sheet.appendChild(document.createTextNode(cssText));
        node.nodeValue = cssText;
        return node;
    })(cssText);
};

Eigenschaften:

  • Die Funktion ist in Vanilla-js geschrieben und bietet daher eine bessere Leistung als jQuery-Alternativen
  • Ein Stylesheet wird nach dem ersten Aufruf von setStyle erstellt. Wenn Sie es also nicht aufrufen, wird kein Stylesheet erstellt.
  • Dasselbe Stylesheet wird für die folgenden Aufrufe von setStyle wiederverwendet.
  • Die Funktion gibt eine Referenz auf den Knoten zurück, der dem von Ihnen hinzugefügten CSS-Bündel zugeordnet ist. Wenn Sie die Funktion erneut mit diesem Knoten als zweites Argument aufrufen, wird das alte CSS durch das neue ersetzt.

Beispiel

var myCSS = setStyle('*{ color:red; }');
setStyle('*{ color:blue; }', myCSS); // Replaces the previous CSS with this one

Browser-Unterstützung

Zumindest funktioniert es auf IE9, FF3, Chrome 1, Safari 4, Opera 10.5.

Es gibt auch eine IE -Version , die sowohl auf modernen Browsern als auch auf älteren Versionen von IE! Funktioniert (funktioniert auf IE8 und IE7, kann aber IE6 abstürzen).

21
Oriol

Gute Frage. Viele der Antworten hier hatten eine Lösung, die direkt dem widersprach, was Sie fragten

"Ich weiß, wie man jQuery verwendet, um einem Element Breite, Höhe usw. zuzuweisen. Ich versuche jedoch, den im Stylesheet definierten Wert so zu ändern, dass der dynamisch erstellte Wert mehreren Elementen zugewiesen werden kann.
"

jQuery .css styles elements inline : Die physikalische CSS-Regel wird dadurch nicht geändert! Wenn Sie dies tun möchten, würde ich vorschlagen, eine JavaScript-Lösung von Vanilla zu verwenden:

document.styleSheets[0].cssRules[0].cssText = "\
     #myID {
         myRule: myValue;
         myOtherRule: myOtherValue;
     }";

Auf diese Weise setzen Sie die Stylesheet-CSS-Regel und fügen keinen Inline-Stil an.

Hoffe das hilft!

18
Jace Cotton

Wie @benvie sagte, ist es effizienter, ein Stylesheet zu ändern, anstatt jQuery.css zu verwenden (das alle Elemente des Sets durchläuft). Es ist auch wichtig, dass Sie nicht jedes Mal, wenn die Funktion aufgerufen wird, einen neuen Stil hinzufügen, da dies zu einem Speicherverlust und zu Tausenden von CSS-Regeln führt, die vom Browser einzeln angewendet werden müssen. Ich würde so etwas machen:

//Add the stylesheet once and store a cached jQuery object
var $style = $("<style type='text/css'>").appendTo('head'); 

function onResize() {
    var css = "\
        .someClass {\
            left:   "+leftVal+";\
            width:  "+widthVal+";\
            height: "+heightVal+";\
        }";

    $style.html(css);
}

Diese Lösung ändert Ihre Stile, indem Sie das DOM nur einmal pro Größenänderung ändern. Beachten Sie, dass Sie für eine effektive J-Minifizierung und -Komprimierung die CSS wahrscheinlich nicht hübsch drucken möchten, aber ich habe es aus Gründen der Klarheit getan.

8
Brian Peacock

Verwenden Sie jquery, um eine Stilüberschreibung im <head> hinzuzufügen:

$('<style>.someClass {color: red;} input::-webkit-outer-spin-button: {display: none;}</style>')
.appendTo('head'); 
5
user2041268

Ich habe eine Lösung zum Ändern eines Werts in bestimmten CSS-Klassen. Es funktioniert jedoch nur, wenn Sie Ihr CSS im Tag behalten. Wenn Sie nur einen Link zu Ihrem CSS von externen Dateien erhalten, z. 

<style src='script.js'></style>

diese Lösung funktioniert nicht.

Wenn Ihre CSS beispielsweise so aussieht: 

<style id='style'>
.foo {
height:50px;
}
</style>

Sie können einen Wert des Tags mit JS/jQuery ändern.

Ich habe eine Funktion geschrieben, die vielleicht nicht die beste ist, aber sie funktioniert. Sie können es verbessern, wenn Sie möchten.

function replaceClassProp(cl,prop,val){

if(!cl || !prop || !val){console.error('Wrong function arguments');return false;}


// Select style tag value

var tag = '#style';

    var style = $(tag).text();
    var str = style;

// Find the class you want to change
    var n = str.indexOf('.'+cl);
    str = str.substr(n,str.length);
    n = str.indexOf('}');
    str = str.substr(0,n+1);

    var before = str;

// Find specific property

    n = str.indexOf(prop);
    str = str.substr(n,str.length);
    n = str.indexOf(';');
    str = str.substr(0,n+1);

// Replace the property with values you selected

    var after = before.replace(str,prop+':'+val+';');
    style=style.replace(before,after);

// Submit changes

    $(tag).text(style);

}

Dann ändern Sie einfach die Tag-Variable in Ihre Stil-Tag-ID und exegute:

replaceClassProp('foo','height','50px');

Der Unterschied zwischen diesem und $ ('. Foo'). Css ('height', '50px'); Wenn Sie dies mit der css-Methode von jQuery tun, haben alle Elemente, die die .foo-Klasse haben, sichtbare style = 'height: 50px' in DOM. Wenn Sie es auf meine Weise tun, bleiben die Elemente unberührt und das einzige, was Sie sehen, ist class = 'foo'.

Vorteile

  • Löschen Sie das DOM
  • Sie können die gewünschte Eigenschaft ändern, ohne den gesamten Stil zu ersetzen

Nachteile

  • Nur internes CSS
  • Sie müssen ein bestimmtes Stil-Tag finden, das Sie bearbeiten möchten

Ich hoffe es hilft trotzdem.

4
wopolow

Sie können die Mitglieder einer CSS-Klasse nicht direkt ändern. Sie können jedoch mit Ihrer neuen Implementierung der css-Klasse auf der Seite ein neues <style>-Tag einführen und dann die Klasse wechseln. Beispiel:

Sample.css

.someClass { border: 1px solid black; font-size: 20px; }

Sie möchten diese Klasse vollständig ändern, sodass Sie ein neues Stilelement erstellen:

<style>
   .someClassReplacement { border: 1px solid white; font-size: 14px; }       
</style>

Sie machen dann einen einfachen Ersatz über jQuery:

$('.someClass').removeClass('someClass').addClass('someClassReplacement');
3
Tejs
function changeStyle(findSelector, newRules) {
    // Change original css style declaration.   
    for ( s in document.styleSheets ) {
        var CssRulesStyle = document.styleSheets[s].cssRules;
        for ( x in CssRulesStyle ) {
            if ( CssRulesStyle[x].selectorText == findSelector) {
                for ( cssprop in newRules ) {
                    CssRulesStyle[x].style[cssprop] = newRules[cssprop];
                }

                return true;
            }
        }
    }

    return false;
}

changeStyle('#exact .myStyle .declaration', {'width':'200px', 'height':'400px', 'color':'#F00'});
2
Cycne

Warum nicht einfach einen Selektor .class verwenden, um die Eigenschaften jedes Objekts in dieser Klasse zu ändern?

dh:

$('.myclass').css('color: red;');

2
JJ.

Okay .. hatte das gleiche Problem und das Problem wurde behoben, aber die Lösung ist möglicherweise nicht für jeden etwas.

Wenn Sie die Indizes des Stylesheets und der Regel kennen, die Sie löschen möchten, versuchen Sie etwas wie document.styleSheets[1].deleteRule(0);.

Ich hatte von Anfang an meine Datei main.css (Index 0). Dann erstellte ich eine neue Datei, js_edit.css (Index 1), die nur eine Regel mit den Eigenschaften enthielt, die ich nach dem Laden der Seite entfernen wollte (auch nach einer Reihe anderer JS-Funktionen).

Nun, da js_edit.css nach main.css geladen wird, können Sie einfach Regeln in js_edit.css einfügen/löschen, wenn Sie möchten, und diese werden in main.css überschrieben.

var x = document.styleSheets[1];
x.insertRule("p { font-size: 2rem; }", x.cssRules.length);

x.cssRules.length gibt die Anzahl der Regeln im zweiten Stylesheet (Index 1) zurück und fügt die neue Regel am Ende ein.

Ich bin sicher, Sie können eine Reihe von for-loops verwenden, um nach der Regel/Eigenschaft zu suchen, die Sie ändern möchten, und dann die gesamte Regel innerhalb desselben Blattes neu zu schreiben, aber ich fand diesen Weg für meine Bedürfnisse einfacher.

http://www.quirksmode.org/dom/w3c_css.html hat mir sehr geholfen.

1
LGT

YUI 2 und 3 verfügt über ein Modul-Stylesheet, mit dem Sie genau das tun können (bearbeiten Sie Stylesheets on the fly mit Javascript). http://yuilibrary.com/yui/docs/stylesheet/ . Ich denke, das ist möglich. Dies ist nicht das Gleiche wie $ (". Some"). Css ({...}), ändert aber wirklich die Stildefinition von Stylesheet, so wie es vom Benutzer verlangt wird.

1
cancerbero

Sie sollten Ihre Herangehensweise an dieses Problem wirklich überdenken. Die Verwendung eines gut entworfenen Selektors und das Anbringen der Klasse kann eine elegantere Lösung für diesen Ansatz sein. Soweit ich weiß, können Sie kein externes CSS ändern.

1
Kevin Bowersox

Diese Lösung ändert Cycne s, um die ES6-Syntax zu verwenden und die Schleife für externe Stylesheets frühzeitig zu beenden. Diese Lösung ändert keine externen Stylesheets

function changeStyle(findSelector, newDeclarations) {
    // Change original css style declaration.
    document.styleSheets.forEach((sheet) => {
      if (sheet.href) return;
      const cssRulesList = sheet.cssRules;
      cssRulesList.forEach((styleRule) => {
        if (styleRule.selectorText === findSelector) {
          Object.keys(newDeclarations).forEach((cssProp) => {
            styleRule.style[cssProp] = newDeclarations[cssProp];
          });
        }
      });
    });
  }

  const styleDeclarations = {
    'width': '200px',
    'height': '400px',
    'color': '#F00'
  };
  changeStyle('.paintBox', styleDeclarations);

Sie müssen beispielsweise auch mindestens ein Stil-Tag in Ihrem HTML-Kopfabschnitt haben

<style> .paintBox {background-color: white;}</style>
0
Tovieye Ozi

Das ist vielleicht zu spät zur Diskussion, aber ich brauchte so etwas wie das, worüber hier gesprochen wird, aber ich habe nichts gefunden, was wirklich das tat, was ich wollte und es leicht machte. Was ich brauchte, war das Verstecken und Anzeigen zahlreicher Elemente, ohne jedes Element einzeln zu besuchen, um sie auf irgendeine Weise zu aktualisieren, die den Anzeigestil in und aus dem Verborgenen veränderte. Also habe ich mir folgendes ausgedacht:

<style>
  /* The bulk of the css rules should go here or in an external css file */
  /* None of these rules will be changed, but may be overridden */
  .aclass { display: inline-block; width: 50px; height: 30px; }
</style>
<style id="style">
  /* Only the rules to be changed should go in this style */
  .bclass { display: inline-block; }
</style>
<script>
  //
  // This is a helper function that returns the named style as an object.
  // This could also be done in other ways.
  // 
  function setStyle() { return document.getElementById( 'style' ); }
</script>
<div id="d1" class="aclass" style="background-color: green;">
  Hi
</div>
<!-- The element to be shown and hidden --> 
<div id="d2" class="aclass bclass" style="background-color: yellow;">
  there
</div>
<div id="d3" class="aclass" style="background-color: lightblue;">
  sailor
</div>
<hr />
<!-- These buttons demonstrate hiding and showing the d3 dive element -->
<button onclick="setStyle().innerHTML = '.bclass { display: none; }';">
  Hide
</button>&nbsp;&nbsp;
<button onclick="setStyle().innerHTML = '.bclass { display: inline-block; }';">
  Show
</button>

Durch Umschalten der Bclass-Regel in dem eingebetteten und benannten Stylesheet, das den anderen relevanten Stylesheets folgt (in diesem Fall mit der Aclass-Regel), könnte ich nur die Regel für die Anzeige-CSS an einer Stelle aktualisieren und die Aclass-Regel überschreiben , die auch eine eigene Anzeigeregel hatte.

Das Schöne an dieser Technik ist, dass sie so einfach ist, dass effektiv eine Zeile die eigentliche Arbeit erledigt. Sie erfordert keine Bibliotheken wie JQuery oder Plug-Ins und die eigentliche Arbeit, alle Stellen zu aktualisieren, an denen sich die Änderungen ändern apply wird von der CSS-Kernfunktionalität des Browsers ausgeführt, nicht in JavaScript. Außerdem funktioniert es in IE 9 und höher, Chrome, Safari, Opera und allen anderen Browsern, die Microsoft Edge für Desktop- und Tablet/Telefone-Geräte emulieren könnte.

0
Howard Brown