Bisakah jQuery mendapatkan semua gaya CSS yang terkait dengan suatu elemen?

297

Apakah ada cara di jQuery untuk mendapatkan semua CSS dari elemen yang ada dan menerapkannya ke yang lain tanpa mendaftar semuanya?

Saya tahu itu akan berhasil jika mereka adalah atribut gaya attr(), tetapi semua gaya saya berada di lembar gaya eksternal.

alex
sumber

Jawaban:

340

Beberapa tahun terlambat, tetapi di sini ada solusi yang mengambil gaya inline dan gaya eksternal:

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

Lulus objek jQuery ke css()dan itu akan mengembalikan objek, yang kemudian dapat Anda pasang kembali ke jQuery's $().css(), mis:

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

:)

marknadal
sumber
14
BTW, ketika Anda mengatakan objek JSON , Anda hanya bermaksud objek JavaScript kan?
alex
3
ini terlihat luar biasa, tetapi ketika saya mencobanya kehilangan pada properti tertentu seperti font-family.
Damon
3
@ Damon: Itu asumsi yang valid, mengingat baris pertama dari jawabannya mengatakan ... berikut adalah solusi yang mengambil kedua inline styling dan styling eksternal .
alex
5
Kode ini tidak berfungsi lagi (selalu mengembalikan objek kosong di Chrome)
Ivan Castellanos
12
Catatan: Moderator telah memodifikasi kode asli saya, saya tidak memberikan jaminan apa pun akan berfungsi.
marknadal
90

Dua tahun terlambat, tapi saya punya solusi yang Anda cari. Tidak bermaksud mengambil kredit dari pembuat aslinya , berikut ini adalah plugin yang saya temukan berfungsi sangat baik untuk apa yang Anda butuhkan, tetapi mendapatkan semua gaya yang mungkin di semua browser, bahkan IE.

Peringatan: Kode ini menghasilkan banyak output, dan harus digunakan dengan hemat. Itu tidak hanya menyalin semua properti CSS standar, tetapi juga semua properti CSS vendor untuk browser itu.

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

Penggunaan dasar cukup sederhana, tapi dia juga menulis fungsi untuk itu:

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

Semoga itu bisa membantu.

Dakota
sumber
2
@Damon: Terima kasih! Saya telah memperbarui posting saya, dan mengedit kata-katanya sedikit untuk memperjelas bahwa ini bukan pekerjaan saya. Maaf tentang kata-kata sebelumnya, saya pikir saya mengetikkan jawaban ini larut malam, tapi bagaimanapun, itu sangat douchey.
Dakota
2
Mengapa ini kembali this.css()? Tidak ada dokumentasi untuk metode ini yang tidak mengambil argumen, dan jika pernyataan ini tercapai, ia mengeluarkan pengecualian. Saya pikir itu akan lebih tepat return returns;bahkan jika itu adalah objek kosong.
Tristan Lee
2
Apakah mungkin untuk mendapatkan demo yang berfungsi ini? Tidak jelas bagi saya di mana harus meletakkan kode ini dan bagaimana memohonnya. Juga tidak jelas bagi saya di mana output disimpan. Terima kasih.
Cymro
Saya tidak mengerti bagaimana cara menggunakannya, Ada sesuatu yang disebut jsfiddle yang kebanyakan orang gunakan untuk membantu. Programmer yang baik adalah guru yang lebih buruk
Gino
@Gino Jika Anda ingin menyalin gaya div1 ke div 2 cukup gunakan: $("#div2").copyCSS($("#div1"));dan untuk mendapatkan gaya elemen apa pun yang dapat Anda gunakan:JSON.stringify($('#element').getStyleObject());
Wessam El Mahdy
16

Mengapa tidak menggunakan .styleelemen DOM ? Ini adalah objek yang berisi anggota seperti widthdan backgroundColor.

strager
sumber
1
Saya cukup yakin ini adalah satu-satunya cara untuk mendapatkan gaya aktual yang terkait dengan kelas. (Berbeda dengan gaya terhitung yang berbeda)
cgp
32
Dengan .style Anda hanya mendapatkan properti yang diterapkan ke atribut gaya elemen, tetapi tidak yang diterapkan dengan kelas CSS.
EricSonaron
+1 sebagai im menggunakan skrip inline dan mengubahnya secara dinamis kata
sandi
11

Saya telah mencoba berbagai solusi. Ini adalah satu-satunya yang bekerja untuk saya karena mampu mengambil gaya yang diterapkan di tingkat kelas dan gaya yang secara langsung dikaitkan dengan elemen. Jadi font ditetapkan pada level file css dan satu sebagai atribut style; itu mengembalikan font yang benar.

Itu sederhana! (Maaf, tidak dapat menemukan tempat saya awalnya menemukannya)

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

Atau Anda dapat membuat daftar semua gaya dengan bersepeda melalui array

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

Solusi @ marknadal tidak mengambil properti yang ditulis dgn tanda penghubung untuk saya (misalnya max-width), tetapi mengubah forloop pertama css2json()membuatnya bekerja, dan saya curiga melakukan iterasi yang lebih sedikit:

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

Loop melalui lengthalih-alih in,mengambil melalui getPropertyValue()alih-alihtoLowerCase().

Brandon Hill
sumber