Kann jQuery alle CSS-Stile abrufen, die einem Element zugeordnet sind?

297

Gibt es in jQuery eine Möglichkeit, alle CSS von einem vorhandenen Element abzurufen und auf ein anderes anzuwenden, ohne sie alle aufzulisten?

Ich weiß, dass es funktionieren würde, wenn sie ein Stilattribut wären attr(), aber alle meine Stile befinden sich in einem externen Stylesheet.

Alex
quelle

Antworten:

340

Ein paar Jahre zu spät, aber hier ist eine Lösung, die sowohl Inline-Styling als auch externes Styling abruft:

function css(a) {
    var sheets = document.styleSheets, o = {};
    for (var i in sheets) {
        var rules = sheets[i].rules || sheets[i].cssRules;
        for (var r in rules) {
            if (a.is(rules[r].selectorText)) {
                o = $.extend(o, css2json(rules[r].style), css2json(a.attr('style')));
            }
        }
    }
    return o;
}

function css2json(css) {
    var s = {};
    if (!css) return s;
    if (css instanceof CSSStyleDeclaration) {
        for (var i in css) {
            if ((css[i]).toLowerCase) {
                s[(css[i]).toLowerCase()] = (css[css[i]]);
            }
        }
    } else if (typeof css == "string") {
        css = css.split("; ");
        for (var i in css) {
            var l = css[i].split(": ");
            s[l[0].toLowerCase()] = (l[1]);
        }
    }
    return s;
}

Übergeben Sie ein jQuery-Objekt an css()und es wird ein Objekt zurückgegeben, das Sie dann wieder in jQuery's einbinden können $().css(), z.

var style = css($("#elementToGetAllCSS"));
$("#elementToPutStyleInto").css(style);

:) :)

Marknadal
quelle
14
Übrigens, wenn Sie ein JSON-Objekt sagen , meinen Sie nur ein JavaScript-Objekt, oder?
alex
3
Das sieht fantastisch aus, aber wenn ich es versuche, fehlen bestimmte Eigenschaften wie die Schriftfamilie.
Damon
3
@Damon: Das ist eine gültige Annahme, wenn man bedenkt, dass in der ersten Zeile der Antwort steht ... hier ist eine Lösung, die sowohl Inline-Styling als auch externes Styling abruft .
alex
5
Dieser Code funktioniert nicht mehr (gibt immer ein leeres Objekt in Chrome zurück)
Ivan Castellanos
12
Hinweis: Moderatoren haben meinen ursprünglichen Code geändert. Ich gebe keine Garantie, dass etwas funktioniert.
Marknadal
90

Zwei Jahre zu spät, aber ich habe die Lösung, die Sie suchen. Ich habe nicht die Absicht, dem ursprünglichen Autor eine Gutschrift zu geben. Hier ist ein Plugin, das meiner Meinung nach außergewöhnlich gut für Ihre Anforderungen funktioniert, aber alle möglichen Stile in allen Browsern, sogar im Internet Explorer, enthält.

Warnung: Dieser Code generiert viel Ausgabe und sollte sparsam verwendet werden. Es werden nicht nur alle Standard-CSS-Eigenschaften kopiert, sondern auch alle Hersteller-CSS-Eigenschaften für diesen Browser.

jquery.getStyleObject.js:

/*
 * getStyleObject Plugin for jQuery JavaScript Library
 * From: http://upshots.org/?p=112
 */

(function($){
    $.fn.getStyleObject = function(){
        var dom = this.get(0);
        var style;
        var returns = {};
        if(window.getComputedStyle){
            var camelize = function(a,b){
                return b.toUpperCase();
            };
            style = window.getComputedStyle(dom, null);
            for(var i = 0, l = style.length; i < l; i++){
                var prop = style[i];
                var camel = prop.replace(/\-([a-z])/g, camelize);
                var val = style.getPropertyValue(prop);
                returns[camel] = val;
            };
            return returns;
        };
        if(style = dom.currentStyle){
            for(var prop in style){
                returns[prop] = style[prop];
            };
            return returns;
        };
        return this.css();
    }
})(jQuery);

Die grundlegende Verwendung ist ziemlich einfach, aber er hat auch eine Funktion dafür geschrieben:

$.fn.copyCSS = function(source){
  var styles = $(source).getStyleObject();
  this.css(styles);
}

Hoffentlich hilft das.

Dakota
quelle
2
@Damon: Danke! Ich habe meinen Beitrag aktualisiert und den Wortlaut leicht bearbeitet, um deutlich zu machen, dass dies nicht meine Arbeit ist. Entschuldigung für den vorherigen Wortlaut, ich glaube, ich habe diese Antwort spät in der Nacht getippt, aber so oder so war es ziemlich douchey.
Dakota
2
Warum kehrt das zurück this.css()? Es gibt keine Dokumentation für diese Methode, die keine Argumente enthält. Wenn diese Anweisung erreicht wird, wird eine Ausnahme ausgelöst. Ich denke, es wäre angemessener, return returns;selbst wenn es ein leeres Objekt ist.
Tristan Lee
2
Wäre es möglich, eine funktionierende Demo davon zu bekommen? Mir ist nicht klar, wo ich diesen Code ablegen und wie ich ihn aufrufen soll. Mir ist auch nicht klar, wo die Ausgabe gespeichert wird. Vielen Dank.
Cymro
Ich verstehe nicht, wie man es benutzt. Es gibt etwas namens jsfiddle, mit dem die meisten Leute helfen. Gute Programmierer sind die schlechteren Lehrer
Gino
@ Gino Wenn Sie den Stil von div1 nach div 2 kopieren möchten, verwenden Sie einfach: $("#div2").copyCSS($("#div1"));und um den Stil eines Elements zu erhalten, das Sie verwenden können:JSON.stringify($('#element').getStyleObject());
Wessam El Mahdy
16

Warum nicht .styledas DOM-Element verwenden ? Es ist ein Objekt, das Mitglieder wie widthund enthält backgroundColor.

Strager
quelle
1
Ich bin mir ziemlich sicher, dass dies der einzige Weg ist, um die tatsächlichen Stile zu erhalten, die der Klasse zugeordnet sind. (im Gegensatz zu den berechneten Stilen, die unterschiedlich sind)
cgp
32
Mit .style erhalten Sie nur Eigenschaften, die auf das style-Attribut des Elements angewendet werden, nicht jedoch solche, die mit einer CSS-Klasse angewendet werden.
EricSonaron
+1 als
ich
11

Ich hatte viele verschiedene Lösungen ausprobiert. Dies war das einzige, das für mich funktioniert hat, da es in der Lage war, Stile aufzunehmen, die auf Klassenebene und auf Stil angewendet wurden, der direkt dem Element zugeordnet wurde. Also eine Schriftart auf CSS-Dateiebene und eine als Stilattribut; Es wurde die richtige Schriftart zurückgegeben.

Es ist einfach! (Entschuldigung, kann nicht finden, wo ich es ursprünglich gefunden habe)

//-- html object
var element = htmlObject; //e.g document.getElementById
//-- or jquery object
var element = htmlObject[0]; //e.g $(selector)

var stylearray = document.defaultView.getComputedStyle(element, null);
var font = stylearray["font-family"]

Alternativ können Sie den gesamten Stil auflisten, indem Sie durch das Array blättern

for (var key in stylearray) {
console.log(key + ': ' + stylearray[key];
}
Valamas
quelle
4

Die Lösung von @ marknadal hat für mich keine getrennten Eigenschaften erfasst (z. B. max-width), aber das Ändern der ersten forSchleife css2json()hat dazu geführt, dass es funktioniert, und ich vermute, dass weniger Iterationen ausgeführt werden:

for (var i = 0; i < css.length; i += 1) {
    s[css[i]] = css.getPropertyValue(css[i]);
}

Schleifen über lengthstatt in,abrufen über getPropertyValue()statttoLowerCase().

Brandon Hill
quelle