読み込み - CSSテキストをJavaScriptオブジェクトに変換する




jquery css (3)

2017年の答え

function parseCSSText(cssText) {
    var cssTxt = cssText.replace(/\/\*(.|\s)*?\*\//g, " ").replace(/\s+/g, " ");
    var style = {}, [,ruleName,rule] = cssTxt.match(/ ?(.*?) ?{([^}]*)}/)||[,,cssTxt];
    var cssToJs = s => s.replace(/\W+\w/g, match => match.slice(-1).toUpperCase());
    var properties = rule.split(";").map(o => o.split(":").map(x => x && x.trim()));
    for (var [property, value] of properties) style[cssToJs(property)] = value;
    return {cssText, ruleName, style};
} /* updated 2017-09-28 */

説明

次のcssText (string)を関数に渡します。

.mybox {
     display: block; 
     width: 20px; 
     height: 20px;
     background-color: rgb(204, 204, 204);
 }

...次のようなオブジェクトになります。

{   cssText: ... /* the original string including new lines, tabs and spaces */, 
    ruleName: ".mybox",
    style: {
        "": undefined,
        display: "block",
        width: "20px",
        height: "20px",
        backgroundColor: "rgb(204, 204, 204)"
     }
}

ユーザーはcssTextようなcssText渡すこともできます。

display: block; width: 20px; height: 20px; background-color: rgb(204, 204, 204);

特徴:

  • CSSRule.cssTextCSSStyleDeclaration.cssText両方でCSSRule.cssTextCSSStyleDeclaration.cssText
  • CSSプロパティ名( background-color )をJSプロパティ名( backgroundColor )に変換します。 back%gr- -ound---color: red;ような非常に不安定な名前でもback%gr- -ound---color: red;backGrOundColor変換しbackGrOundColor )。
  • 単一の呼び出しObject.assign(document.body.style, parseCSSText(cssText).style)を使用して、既存のCSSStyleDeclarationsdocument.body.styleなど)の一括変更を有効にします。
  • プロパティ名が値なし(コロンなしのエントリ)であっても失敗しませ。逆も同様です。
  • 更新2017-09-28:ルール名でも新しい行を処理し、空白を折りたたみます。
  • 更新2017-09-28:コメントを処理します( /*...*/ )。

癖:

  • ルール内の最後のCSS宣言がセミコロンで終わっている場合、返されるスタイルには空の名前""と、セミコロンに続くNULL文字列を反映したundefined値を持つプロパティが含まれます。 それは正しい振る舞いだと思います。
  • プロパティ値(文字列リテラル)にコロン、セミコロン、CSSのコメントが含まれている場合、関数は誤った結果を返しdiv::before {content: 'test:test2;/*test3*/';}例えばdiv::before {content: 'test:test2;/*test3*/';}ます。 これを回避する方法がわかりません。
  • 現時点では、 -somebrowser-somepropertyなどの接頭辞を持つプロパティ名をSomebrowserSomepropertyではなく-somebrowser-someproperty誤って変換します。 コードの簡潔さを損なわないような解決策が必要です。そのため、見つけるのに時間がかかります。

実例

function parseCSSText(cssText) {
    var cssTxt = cssText.replace(/\/\*(.|\s)*?\*\//g, " ").replace(/\s+/g, " ");
    var style = {}, [,ruleName,rule] = cssTxt.match(/ ?(.*?) ?{([^}]*)}/)||[,,cssTxt];
    var cssToJs = s => s.replace(/\W+\w/g, match => match.slice(-1).toUpperCase());
    var properties = rule.split(";").map(o => o.split(":").map(x => x && x.trim()));
    for (var [property, value] of properties) style[cssToJs(property)] = value;
    return {cssText, ruleName, style};
} /* updated 2017-09-28 */

Example:
    var sty = document.getElementById("mystyle");
    var out = document.getElementById("outcome");
    var styRule = parseCSSText(sty.innerHTML);
    var outRule = parseCSSText(out.style.cssText);
    out.innerHTML = 
        "<b>⦁ CSS in #mystyle</b>: " + JSON.stringify(styRule) + "<br>" +
        "<b>⦁ CSS of #outcome</b>: " + JSON.stringify(outRule);
    console.log(styRule, outRule); /* Inspect result in the console. */
<style id="mystyle">
.mybox1, /* a comment
    and new lines 
    to step up the game */
    .mybox 
{
    display: block; 
    width: 20px; height: 20px;
    background-color: /* a comment
        and a new line */ 
        rgb(204, 204, 204);
    -somebrowser-someproperty: somevalue;
}
</style>

<div id="outcome" style="
    display: block; padding: 0.5em;
    background-color: rgb(144, 224, 224);
">...</div>

<b style="color: red;">Also inspect the browser console.</b>

JavaScriptの文字列として以下のテキストを持っています

.mybox {
 display: block; 
 width: 20px; 
 height: 20px;
 background-color: rgb(204, 204, 204);
 }

JavaScriptオブジェクトに変換したい

var mybox = {
 'display': 'block',
 'width': '20px',
 'height': '20px';
 'background-color': 'rgb(204, 204, 204)';
};

任意のアイデアやすでに作られたスクリプト?


CSSドキュメントがhtmlドキュメントに含まれていて、スタイル宣言が実際に読み込まれるようになっている場合は、Javascriptですべてのスタイルを次のように進めることができます。

// Get all style sheet documents in this html document
var allSheets = document.styleSheets;

for (var i = 0; i < allSheets.length; ++i) {
    var sheet = allSheets[i];

    // Get all CSS rules in the current style sheet document
    var rules = sheet.cssRules || sheet.rules;
    for (var j = 0; j < rules.length; ++j) {
        var rule = rules[j];

        // Get the selector definition ("div > p:first-child" for example)
        var selector = rule.selectorText;

        // Create an empty object to put the style definitions in
        var result = {};

        var style = rule.style;
        for (var key in style) {
            if (style.hasOwnProperty(key)) {
                result[key] = style.cssText;
            }
        }

        // At this point, you have the selector in the
        // selector variable (".mybox" for example)

        // You also have a javascript object in the
        // result variable, containing what you need.

        // If you need to output this as json, there
        // are several options for this.
    }
}

CSSドキュメントを解析してJavaScriptソースファイルを作成したい場合のように、これが望まない場合は、字句解析プログラム、CSSドキュメントオブジェクトモデル、JSONシリアライゼーションなどを検討する必要があります。


私はLeafLetがJavaScriptコードからCSSスタイルを分離しようとしているのと同じ問題を抱えています...私はこれで終わります:

var css = {};

for (var i = 0; i < document.styleSheets.length; ++i) {
    var sheet = document.styleSheets[i];
    for (var j = 0; j < sheet.cssRules.length; ++j) {
        var rule = sheet.cssRules[j];

        var cssText = rule.cssText.slice(rule.cssText.indexOf('{')+1);
        var attrs = cssText.split(';');

        var ruleSet = {};
        for (var k = 0; k < attrs.length; ++k) {
            var keyValue = attrs[k].split(':');
            if (keyValue.length == 2) {
                var key = keyValue[0].trim();
                var value = keyValue[1].trim();
                ruleSet[key] = value;
            }
        }

        for (var testRule in ruleSet) { // We are going to add the rule iff it is not an empty object
            css[rule.selectorText] = ruleSet;
            break;
        }
    }
}

console.log(css);

これはこのような何かを生み出すでしょう:







css