Получить значение CSS из внешней таблицы стилей с помощью Javascript/jQuery


можно ли получить значение из внешнего CSS страницы, если элемент, на который ссылается стиль, еще не был сгенерирован? (элемент должен быть сгенерирован динамически).

метод jQuery, который я видел, это $('element').css('property');, но это зависит от element на странице. Есть ли способ узнать, что свойство установлено в CSS, а не вычисленный стиль элемента?

мне придется сделать что-то уродливое, как добавить скрытую копию элемент на мою страницу, чтобы я мог получить доступ к его атрибутам стиля?

5 58

5 ответов:

С помощью jQuery:

// Scoping function just to avoid creating a global
(function() {
    var $p = $("<p></p>").hide().appendTo("body");
    console.log($p.css("color"));
    $p.remove();
})();
p {color: blue}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

использование DOM напрямую:

// Scoping function just to avoid creating a global
(function() {
    var p = document.createElement('p');
    document.body.appendChild(p);
    console.log(getComputedStyle(p).color);
    document.body.removeChild(p);
})();
p {color: blue}

Примечание: в обоих случаях, если вы загружаете внешние таблицы стилей, вам нужно будет дождаться их загрузки, чтобы увидеть их влияние на элемент. Ни jQuery ready ни дом DOMContentLoaded событие делает это, вы должны были бы обеспечить его наблюдая за ними, чтобы загрузить.

JSFiddle)

function getStyleSheetPropertyValue(selectorText, propertyName) {
    // search backwards because the last match is more likely the right one
    for (var s= document.styleSheets.length - 1; s >= 0; s--) {
        var cssRules = document.styleSheets[s].cssRules ||
                document.styleSheets[s].rules || []; // IE support
        for (var c=0; c < cssRules.length; c++) {
            if (cssRules[c].selectorText === selectorText) 
                return cssRules[c].style[propertyName];
        }
    }
    return null;
}

alert(getStyleSheetPropertyValue("p", "color"));

обратите внимание, что это довольно хрупко, так как вы должны предоставить полный текст селектора, который соответствует правилу, которое вы ищете (он не анализируется), и он не обрабатывает повторяющиеся записи или какие-либо правила приоритета. Трудно мне думать о случае, когда это было бы хорошей идеей, но здесь это просто пример.

в ответ на Karim79 я просто подумал, что выброшу свою функциональную версию этого ответа. Мне пришлось сделать это несколько раз, так это то, что я написал:

function getClassStyles(parentElem, selector, style){
    elemstr = '<div '+ selector +'></div>';
    var $elem = $(elemstr).hide().appendTo(parentElem);
        val = $elem.css(style);
    $elem.remove();
    return val;
}
val = getClassStyles('.container:first', 'class="title"', 'margin-top');
console.warn(val);

в этом примере предполагается, что у вас есть и элемент с class="container", и вы ищете стиль margin-top класса заголовка в этом элементе. Конечно, изменить в соответствии с вашими потребностями.

в таблице стилей:

 .container .title{ margin-top:num; }

позвольте мне знать, что вы думаете - вы бы изменить его, и если да, то как? Спасибо!

Я написал вспомогательную функцию, которая принимает объект с атрибутами css для извлечения из данного класса css и заполняет фактические значения атрибутов css. Пример включен.

function getStyleSheetValues(colScheme) {
    var tags='';
    var obj= colScheme;

    // enumerate css classes from object
    for (var prop in obj) { 
        if (obj.hasOwnProperty(prop) && typeof obj[prop]=="object") { 
            tags+= '<span class="'+prop+'"></span>';
        } 
    } 

    // generate an object that uses the given classes
    tags= $('<div>'+tags+'</div>').hide().appendTo("body");

    // read the class properties from the generated object
    var idx= 0;
    for (var prop in obj) { 
        if (obj.hasOwnProperty(prop) && typeof obj[prop]=="object") { 
            var nobj= obj[prop];
            for (var nprop in nobj) { 
                if (nobj.hasOwnProperty(nprop) && typeof(nobj[nprop])=="string") { 
                    nobj[nprop]= tags.find("span:eq("+idx+")").css(nobj[nprop]);
                }
            }
            idx++;
        } 
    } 
    tags.remove();
}

// build an object with css class names where each class name contains one 
// or more properties with an arbitrary name and the css attribute name as its value.
// This value will be replaced by the actual css value for the respective class.
var colorScheme= { chart_wall: {wallColor:'background-color',wallGrid:'color'}, chart_line1: { color:'color'} };

$(document).ready(function() {
    getStyleSheetValues(colorScheme);

    // debug: write the property values to the console;     
    if (window.console) {
        var obj= colorScheme;
        for (var prop in obj) { 
            if (obj.hasOwnProperty(prop) && typeof obj[prop]=="object") { 
                var nobj= obj[prop];
                for (var nprop in nobj) { 
                    if (nobj.hasOwnProperty(nprop)) { 
                        console.log(prop+'.'+nprop +':'+ nobj[nprop]);
                    }
                }
            } 
        } 
        // example of how to read an individual css attribute value
        console.log('css value for chart_wall.wallGrid: '+colorScheme.chart_wall.wallGrid);
    }
});

Я написал эту функцию js, кажется, работает и для вложенных классов:

использование:

var style = get_css_property('.container-class .sub-container-class .child-class', 'margin');
console.log('style');


function get_css_property(class_name, property_name){
    class_names = class_name.split(/\s+/);
    var container = false;
    var child_element = false;

    for (var i = class_names.length - 1; i >= 0; i--) {
        if(class_names[i].startsWith('.'))
            class_names[i] = class_names[i].substring(1);
        var new_element = $.parseHTML('<div class="' + class_names[i] + '"></div>');
        if(!child_element)
            child_element = new_element;
        if(container)
            $(new_element).append(container);
        container = new_element;
    }
    $(container).hide().appendTo('body');
    var style = $(child_element).css(property_name);
    $(container).remove();
    return style;
}