Чи може jQuery отримати всі стилі CSS, пов'язані з елементом?


297

Чи є в jQuery спосіб отримати всі CSS з існуючого елемента та застосувати його до іншого, не перераховуючи їх усіх?

Я знаю, що це би спрацювало, якби вони були атрибутом стилю attr(), але всі мої стилі знаходяться у зовнішньому стилі.

Відповіді:


340

На пару років пізніше, але ось рішення, яке отримує як вбудований стиль, так і зовнішній стиль:

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

Передайте об'єкт jQuery, css()і він поверне об'єкт, який ви можете потім підключити назад до jQuery $().css(), наприклад:

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

:)


14
До речі, коли ви говорите об'єкт JSON , ви просто маєте на увазі об’єкт JavaScript, правда?
alex

3
це виглядає приголомшливо, але коли я намагаюся це не вистачає певних властивостей, таких як сімейство шрифтів.
Деймон

3
@Damon: Це обгрунтоване припущення, враховуючи перший рядок відповіді ... ось рішення, яке витягує як вбудований стиль, так і зовнішній стиль .
alex

5
Цей код більше не працює (завжди повертає порожній об’єкт у Chrome)
Іван Кастелланос,

12
Примітка: Модератори змінили мій початковий код, я не даю гарантії, що нічого не вийде.
marknadal

90

На два роки пізно, але у мене є рішення, яке ви шукаєте. Не маючи наміру брати кредитну форму від оригінального автора , ось плагін, який я знайшов, працює надзвичайно добре для того, що вам потрібно, але отримує всі можливі стилі у всіх браузерах, навіть IE.

Попередження: Цей код генерує велику кількість результатів, і його слід використовувати ощадливо. Він не тільки копіює всі стандартні властивості CSS, але і всі властивості CSS постачальника для цього браузера.

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

Основне використання досить просте, але він також для цього написав функцію:

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

Сподіваюся, що це допомагає.


2
@Damon: Дякую! Я оновив свою посаду і трохи відредагував формулювання, щоб зрозуміти, що це не моя робота. Вибачте за попереднє формулювання, я думаю, що я набрав цю відповідь пізно вночі, але в будь-якому випадку, це було досить душе.
Дакота

2
Чому це повертається this.css()? Немає жодної документації для цього методу, яка не містить аргументів, і якщо це твердження буде досягнуто, це викидає виняток. Я думаю, це було б доречніше, return returns;навіть якщо це порожній предмет.
Трістан Лі

2
Чи можна було б отримати робочу демонстрацію цього? Незрозуміло мені, куди поставити цей код і як його викликати. Також мені незрозуміло, де зберігається вихід. Дякую.
Кімро

Я не розумію, як ним користуватися. Є щось, що називається jsfiddle, що більшість людей використовує для допомоги. Хороший програміст - гірший вчитель
Джино

@Gino Якщо ви хочете скопіювати стиль div1 в div 2, просто використовуйте: $("#div2").copyCSS($("#div1"));і щоб отримати стиль будь-якого елемента, який ви можете використовувати:JSON.stringify($('#element').getStyleObject());
Wessam El Mahdy

16

Чому б не використовувати .styleелемент DOM ? Це об'єкт, який містить членів, таких як widthі backgroundColor.


1
Я впевнений, що це єдиний спосіб отримати фактичні стилі, пов'язані з класом. (на відміну від обчислених стилів, які відрізняються)
cgp

32
За допомогою .style ви отримуєте лише властивості, застосовані до атрибуту стилю елемента, але не ті, які застосовуються до класу CSS.
EricSonaron

+1, як я, використовуючи вбудований сценарій і динамічно змінюючи його післямови
user991554

11

Я спробував багато різних рішень. Це єдине, що працювало для мене тим, що він міг підбирати стилі, застосовані на рівні класу та в стилі, як безпосередньо приписано елементу. Отже, шрифт встановлений на рівні файлу css і один як атрибут стилю; він повернув правильний шрифт.

Це просто! (Вибачте, не можу знайти, де я його спочатку знайшов)

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

Крім того, ви можете перелічити весь стиль, проїхавши по масиву

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


4

Рішення @ marknadal для мене не захоплювало дефісні властивості (наприклад max-width), але зміна першої forпетлі в css2json()цьому спрацювала, і я підозрюю, що виконує меншу кількість ітерацій:

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

Цикли через, lengthа не in,отримує через, getPropertyValue()а неtoLowerCase().

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.