O jQuery pode obter todos os estilos CSS associados a um elemento?


297

Existe uma maneira no jQuery obter todo o CSS de um elemento existente e aplicá-lo a outro sem listar todos eles?

Eu sei que funcionaria se eles fossem um atributo de estilo attr(), mas todos os meus estilos estão em uma folha de estilos externa.

Respostas:


340

Alguns anos atrasado, mas aqui está uma solução que recupera o estilo embutido e o externo:

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

Passe um objeto jQuery css()e ele retornará um objeto, que você poderá conectar novamente ao jQuery $().css(), ex:

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

:)


14
BTW, quando você diz um objeto JSON , você quer dizer apenas um objeto JavaScript, certo?
28411 alex

3
isso parece incrível, mas quando estou tentando, perde algumas propriedades, como família de fontes.
Damon

3
@ Damon: Essa é uma suposição válida, considerando que a primeira linha da resposta diz ... aqui está uma solução que recupera o estilo em linha e o estilo externo .
alex

5
Este código não funciona mais (sempre retorna objeto vazio no Chrome)
Ivan Castellanos

12
Nota: Os moderadores modificaram meu código original, não garanto que tudo funcione.
marknadal

90

Dois anos atrasado, mas eu tenho a solução que você está procurando. Não pretendendo assumir o crédito do autor original , aqui está um plugin que eu achei que funciona excepcionalmente bem para o que você precisa, mas obtém todos os estilos possíveis em todos os navegadores, até no IE.

Aviso: Este código gera muita saída e deve ser usado com moderação. Ele não apenas copia todas as propriedades CSS padrão, mas também todas as propriedades CSS do fornecedor para esse navegador.

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

O uso básico é bastante simples, mas ele também escreveu uma função para isso:

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

Espero que ajude.


2
@ Damon: Obrigado! Atualizei minha postagem e editei um pouco o texto para deixar claro que esse não é meu trabalho. Desculpe pela redação anterior, acho que digitei essa resposta tarde da noite, mas de qualquer forma, foi bastante idiota.
Dakota

2
Por que isso retorna this.css()? Não há documentação para este método sem argumentos, e se essa instrução for atingida, ela lança uma exceção. Eu acho que seria mais apropriado, return returns;mesmo que seja um objeto vazio.
Tristan Lee

2
Seria possível obter uma demonstração funcional disso? Não está claro para mim onde colocar esse código e como invocá-lo. Também não está claro para mim onde a saída está sendo armazenada. Obrigado.
Cymro

Eu não entendo como usá-lo. Existe algo chamado jsfiddle que a maioria das pessoas usa para ajudar. Bom programador é o professor pior
Gino

@Gino Se você deseja copiar o estilo de div1 para div 2 uso apenas: $("#div2").copyCSS($("#div1"));e para obter o estilo de qualquer elemento que você poderia usar:JSON.stringify($('#element').getStyleObject());
Wessam El Mahdy

16

Por que não usar .styleo elemento DOM ? É um objeto que contém membros como widthe backgroundColor.


1
Tenho certeza de que essa é a única maneira de obter os estilos reais associados à classe. (em oposição aos estilos calculados que são diferentes) #
1613

32
Com .style, você obtém apenas propriedades aplicadas ao atributo style do elemento, mas não aquelas aplicadas com uma classe CSS.
EricSonaron

+1 como im usando script embutido e mudá-lo de forma dinâmica afterwords
user991554

11

Eu tentei muitas soluções diferentes. Esse foi o único que funcionou para mim, pois foi capaz de captar os estilos aplicados no nível da classe e no estilo, como diretamente atribuídos ao elemento. Portanto, uma fonte definida no nível do arquivo css e outra como um atributo de estilo; retornou a fonte correta.

É simples! (Desculpe, não consigo encontrar onde o encontrei originalmente)

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

Como alternativa, você pode listar todo o estilo percorrendo a matriz

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


4

A solução do @ marknadal não estava pegando propriedades hifenizadas para mim (por exemplo max-width), mas alterar o primeiro forloop css2json()fez com que funcionasse, e suspeito que realiza menos iterações:

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

Loops via em lengthvez de in,recupera via em getPropertyValue()vez detoLowerCase().

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.