JQuery có thể có được tất cả các kiểu CSS được liên kết với một phần tử không?


297

Có cách nào trong jQuery để lấy tất cả CSS từ một phần tử hiện có và áp dụng nó cho phần tử khác mà không liệt kê tất cả chúng không?

Tôi biết nó sẽ hoạt động nếu chúng là một thuộc tính kiểu attr(), nhưng tất cả các kiểu của tôi đều nằm trong một biểu định kiểu bên ngoài.

Câu trả lời:


340

Một vài năm muộn màng, nhưng đây là một giải pháp lấy cả kiểu dáng nội tuyến và kiểu dáng bên ngoài:

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

Truyền một đối tượng jQuery vào css()và nó sẽ trả về một đối tượng, sau đó bạn có thể cắm lại vào jQuery $().css(), ví dụ:

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

:)


14
BTW, khi bạn nói một đối tượng JSON , bạn chỉ có nghĩa là một đối tượng JavaScript phải không?
alex

3
Điều này có vẻ tuyệt vời, nhưng khi tôi thử nó, nó bỏ lỡ một số thuộc tính nhất định như họ phông chữ.
Damon

3
@Damon: Đó là một giả định hợp lệ, xem xét dòng đầu tiên của câu trả lời cho biết ... đây là một giải pháp lấy cả kiểu dáng nội tuyến và kiểu dáng bên ngoài .
alex

5
Mã này không còn hoạt động nữa (luôn trả về đối tượng trống trong Chrome)
Ivan Castellanos

12
Lưu ý: Người điều hành đã sửa đổi mã gốc của tôi, tôi không đảm bảo mọi thứ sẽ hoạt động.
đánh dấu

90

Hai năm muộn, nhưng tôi có giải pháp bạn đang tìm kiếm. Không có ý định lấy tín dụng từ tác giả ban đầu , đây là một plugin mà tôi thấy hoạt động cực kỳ tốt cho những gì bạn cần, nhưng có tất cả các kiểu có thể có trong tất cả các trình duyệt, thậm chí cả IE.

Cảnh báo: Mã này tạo ra rất nhiều đầu ra và nên được sử dụng một cách tiết kiệm. Nó không chỉ sao chép tất cả các thuộc tính CSS tiêu chuẩn, mà còn tất cả các thuộc tính CSS của nhà cung cấp cho trình duyệt đó.

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

Cách sử dụng cơ bản khá đơn giản, nhưng anh ấy cũng đã viết một chức năng cho điều đó:

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

Mong rằng sẽ giúp.


2
@Damon: Cảm ơn! Tôi đã cập nhật bài viết của mình và chỉnh sửa từ ngữ một chút để làm rõ rằng đây không phải là công việc của tôi. Xin lỗi về cách diễn đạt trước đó, tôi nghĩ rằng tôi đã gõ câu trả lời này vào đêm khuya, nhưng dù sao đi nữa, nó khá là douchey.
Dakota

2
Tại sao điều này trở lại this.css()? Không có tài liệu nào cho phương thức này không có đối số và nếu đạt được tuyên bố này, nó sẽ đưa ra một ngoại lệ. Tôi nghĩ rằng nó sẽ phù hợp hơn return returns;ngay cả khi đó là một vật thể rỗng.
Tristan Lee

2
Nó sẽ có thể có được một bản demo làm việc này? Tôi không rõ nơi để đặt mã này và làm thế nào để gọi nó. Nó cũng không rõ ràng cho tôi nơi đầu ra đang được lưu trữ. Cảm ơn.
Cymro

Tôi không hiểu làm thế nào để sử dụng nó, Có một thứ gọi là jsfiddle mà hầu hết mọi người sử dụng để giúp đỡ. Lập trình viên giỏi là giáo viên tồi hơn
Gino

@Gino Nếu bạn muốn sao chép kiểu của div1 sang div 2, chỉ cần sử dụng: $("#div2").copyCSS($("#div1"));và để có được kiểu của bất kỳ yếu tố nào bạn có thể sử dụng:JSON.stringify($('#element').getStyleObject());
Wessam El Mahdy

16

Tại sao không sử dụng .stylephần tử DOM ? Đó là một đối tượng có chứa các thành viên như widthbackgroundColor.


1
Tôi khá chắc chắn rằng đây là cách duy nhất để có được các kiểu thực tế liên quan đến lớp. (trái ngược với các kiểu tính toán khác nhau)
cgp

32
Với .style bạn chỉ nhận được các thuộc tính được áp dụng cho thuộc tính style của phần tử, chứ không phải các thuộc tính được áp dụng với lớp CSS.
EricSonaron

+1 là tôi đang sử dụng tập lệnh nội tuyến và thay đổi nó một cách linh hoạt lời bạt
user991554

11

Tôi đã thử nhiều giải pháp khác nhau. Đây là người duy nhất làm việc cho tôi ở chỗ nó có thể chọn các kiểu được áp dụng ở cấp lớp và ở kiểu như được gán trực tiếp vào phần tử. Vì vậy, một phông chữ được đặt ở cấp tệp css và một phông làm thuộc tính kiểu; Nó trả lại đúng phông chữ.

Nó đơn giản! (Xin lỗi, không thể tìm thấy nơi tôi tìm thấy ban đầu)

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

Ngoài ra, bạn có thể liệt kê tất cả các phong cách bằng cách đạp xe qua mảng

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


4

Giải pháp của @ marknadal không lấy các thuộc tính gạch nối cho tôi (ví dụ max-width), nhưng thay đổi forvòng lặp đầu tiên để css2json()nó hoạt động và tôi nghi ngờ thực hiện ít lần lặp hơn:

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

Vòng lặp thông qua lengththay vì in,truy xuất thông qua getPropertyValue()chứ không phảitoLowerCase().

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.