JQuery può associare tutti gli stili CSS a un elemento?


297

C'è un modo in jQuery per ottenere tutti i CSS da un elemento esistente e applicarlo a un altro senza elencarli tutti?

So che funzionerebbe se fossero un attributo di stile attr(), ma tutti i miei stili sono in un foglio di stile esterno.

Risposte:


340

Un paio d'anni in ritardo, ma ecco una soluzione che recupera sia lo stile in linea che lo stile esterno:

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

Passa un oggetto jQuery in css()e restituirà un oggetto, che puoi quindi ricollegare in jQuery $().css(), ad esempio:

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

:)


14
A proposito, quando dici un oggetto JSON , intendi solo un oggetto JavaScript giusto?
alex

3
sembra fantastico, ma quando ci provo manca alcune proprietà come la famiglia di caratteri.
Damon,

3
@Damon: questo è un presupposto valido, considerando la prima riga della risposta dice ... ecco una soluzione che recupera sia lo stile in linea che lo stile esterno .
alex

5
Questo codice non funziona più (restituisce sempre un oggetto vuoto in Chrome)
Ivan Castellanos

12
Nota: i moderatori hanno modificato il mio codice originale, non do alcuna garanzia che funzionerà.
marknadal,

90

Due anni di ritardo, ma ho la soluzione che stai cercando. Non intendendo prendere il merito dall'autore originale , ecco un plugin che ho trovato funziona eccezionalmente bene per quello che ti serve, ma ottiene tutti gli stili possibili in tutti i browser, anche IE.

Avvertimento: questo codice genera molto output e deve essere usato con parsimonia. Copia non solo tutte le proprietà CSS standard, ma anche tutte le proprietà CSS del fornitore per quel 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);

L'uso di base è piuttosto semplice, ma ha scritto anche una funzione per questo:

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

Spero che aiuti.


2
@Damon: grazie! Ho aggiornato il mio post e modificato leggermente il testo per chiarire che questo non è il mio lavoro. Mi dispiace per la frase precedente, penso di aver scritto questa risposta fino a tarda notte, ma in entrambi i casi, è stato piuttosto schifoso.
Dakota,

2
Perché questo ritorna this.css()? Non esiste documentazione per questo metodo che non accetta argomenti e, se viene raggiunta questa affermazione, viene generata un'eccezione. Penso che sarebbe più appropriato return returns;anche se si tratta di un oggetto vuoto.
Tristan Lee,

2
Sarebbe possibile ottenere una demo funzionante di questo? Non mi è chiaro dove mettere questo codice e come invocarlo. Inoltre, non mi è chiaro dove venga archiviato l'output. Grazie.
Cymro

Non capisco come usarlo, c'è qualcosa chiamato jsfiddle che la maggior parte delle persone usa per aiutare. Un buon programmatore è l'insegnante peggiore
Gino,

@Gino Se vuoi copiare lo stile di div1 in div 2 basta usare: $("#div2").copyCSS($("#div1"));e per ottenere lo stile di qualsiasi elemento che potresti usare:JSON.stringify($('#element').getStyleObject());
Wessam El Mahdy,

16

Perché non utilizzare .stylel'elemento DOM ? È un oggetto che contiene membri come widthe backgroundColor.


1
Sono abbastanza sicuro che questo sia l'unico modo per ottenere gli stili reali associati alla classe. (al contrario degli stili calcolati che sono diversi)
CG

32
Con .style ottieni solo proprietà applicate all'attributo style dell'elemento, ma non quelle applicate con una classe CSS.
EricSonaron,

+1 come
sto

11

Avevo provato molte soluzioni diverse. Questo è stato l'unico che ha funzionato per me in quanto è stato in grado di raccogliere stili applicati a livello di classe e stile come attribuito direttamente sull'elemento. Quindi un font impostato a livello di file css e uno come attributo di stile; ha restituito il carattere corretto.

È semplice! (Spiacente, non riesco a trovare dove l'ho trovato originariamente)

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

In alternativa, puoi elencare tutto lo stile scorrendo l'array

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


4

La soluzione di @ marknadal non stava afferrando le proprietà sillabate per me (ad es. max-width), ma cambiando il primo forciclo in css2json()funzionava, e sospetto che esegua meno iterazioni:

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

Passa tramite lengthanziché in,recupera tramite getPropertyValue()anzichétoLowerCase().

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.