JQuery peut-il obtenir tous les styles CSS associés à un élément?

297

Existe-t-il un moyen dans jQuery d'obtenir tous les CSS d'un élément existant et de les appliquer à un autre sans les répertorier tous?

Je sais que cela fonctionnerait s'ils étaient un attribut de style avec attr(), mais tous mes styles sont dans une feuille de style externe.

alex
la source

Réponses:

340

Quelques années de retard, mais voici une solution qui récupère à la fois le style en ligne et le style externe:

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

Passez un objet jQuery dans css()et il retournera un objet, que vous pourrez ensuite rebrancher dans jQuery $().css(), ex:

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

:)

marknadal
la source
14
BTW, quand vous dites un objet JSON , vous voulez juste dire un objet JavaScript non?
alex
3
cela a l'air génial, mais quand je l'essaye, il manque certaines propriétés telles que la famille de polices.
Damon
3
@Damon: C'est une hypothèse valide, étant donné que la première ligne de la réponse dit ... voici une solution qui récupère à la fois le style en ligne et le style externe .
alex
5
Ce code ne fonctionne plus (renvoie toujours un objet vide dans Chrome)
Ivan Castellanos
12
Remarque: les modérateurs ont modifié mon code d'origine, je ne donne aucune garantie que tout fonctionnera.
marknadal
90

Deux ans de retard, mais j'ai la solution que vous cherchez. N'ayant pas l'intention de prendre le crédit de l' auteur d'origine , voici un plugin qui, selon moi, fonctionne exceptionnellement bien pour ce dont vous avez besoin, mais obtient tous les styles possibles dans tous les navigateurs, même IE.

Avertissement: ce code génère beaucoup de résultats et doit être utilisé avec parcimonie. Il copie non seulement toutes les propriétés CSS standard, mais également toutes les propriétés CSS du fournisseur pour ce navigateur.

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

L'utilisation de base est assez simple, mais il a également écrit une fonction pour cela:

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

J'espère que cela pourra aider.

Dakota
la source
2
@Damon: Merci! J'ai mis à jour mon article et j'ai légèrement modifié le libellé pour qu'il soit clair que ce n'est pas mon travail. Désolé pour la formulation précédente, je pense que j'ai tapé cette réponse tard dans la nuit, mais de toute façon, c'était plutôt foutu.
Dakota
2
Pourquoi cela revient-il this.css()? Il n'y a pas de documentation pour cette méthode ne prenant aucun argument, et si cette instruction est atteinte, elle lève une exception. Je pense qu'il serait plus approprié return returns;même si c'est un objet vide.
Tristan Lee
2
Serait-il possible d'en obtenir une démo fonctionnelle? Pas clair pour moi où mettre ce code et comment l'invoquer. Je ne sais pas non plus où la sortie est stockée. Merci.
Cymro
Je ne comprends pas comment l'utiliser, il y a quelque chose appelé jsfiddle que la plupart des gens utilisent pour aider. Un bon programmeur est le pire professeur
Gino
@Gino Si vous voulez copier le style de div1 vers div 2, utilisez simplement: $("#div2").copyCSS($("#div1"));et pour obtenir le style de tout élément que vous pourriez utiliser:JSON.stringify($('#element').getStyleObject());
Wessam El Mahdy
16

Pourquoi ne pas utiliser .stylel'élément DOM ? C'est un objet qui contient des membres tels que widthet backgroundColor.

strager
la source
1
Je suis presque sûr que c'est le seul moyen d'obtenir les styles réels associés à la classe. (par opposition aux styles calculés qui sont différents)
cgp
32
Avec .style, vous obtenez uniquement les propriétés appliquées à l'attribut style de l'élément, mais pas celles appliquées avec une classe CSS.
EricSonaron
+1 comme im en utilisant un script en ligne et en le changeant dynamiquement afterwords
user991554
11

J'avais essayé de nombreuses solutions différentes. C'est le seul qui a fonctionné pour moi en ce sens qu'il a pu reprendre les styles appliqués au niveau de la classe et au style directement attribué à l'élément. Donc, une police définie au niveau du fichier CSS et une comme attribut de style; il a renvoyé la police correcte.

C'est simple! (Désolé, je ne trouve pas où je l'ai trouvé à l'origine)

//-- 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"]

Alternativement, vous pouvez lister tout le style en parcourant le tableau

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

La solution de @ marknadal ne récupérait pas les propriétés coupées pour moi (par exemple max-width), mais changer la première forboucle en css2json()faisait fonctionner, et je soupçonne d'effectuer moins d'itérations:

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

Boucle via lengthplutôt que in,récupère via getPropertyValue()plutôt quetoLowerCase().

Brandon Hill
la source