【问题标题】:Replacing class styles with inline styles用内联样式替换类样式
【发布时间】:2017-03-13 20:46:14
【问题描述】:

我有 svg 图像,其中有一些类(jointJS 论文)。我正在保存这个 svg,然后在后端将其转换为 png 文件。问题是 - 我的后端的类无法识别,所以我想用分配给这些类的样式替换类名,例如。

<g id=\"j_42\" model-id=\"7c170ce6-09a5-49e9-b470-c1bb1980bd02\" class=\"link joint-theme-default\"><path class=\"connection\" stroke=\"#222\" d=\"M 803 387 C 881 387 881 196 959 196\" id=\"v-522\" stroke-width=\"3\"/>

<g id=\"j_42\" model-id=\"7c170ce6-09a5-49e9-b470-c1bb1980bd02\" style="some_styles_that_stands_for joint-theme-default class"><path class=\"connection\" stroke=\"#222\" d=\"M 803 387 C 881 387 881 196 959 196\" id=\"v-522\" stroke-width=\"3\"/

【问题讨论】:

    标签: css arrays svg imagemagick-convert jointjs


    【解决方案1】:

    您可以使用document.styleSheets 读取所有样式表,找到您想要的所有类规则并将元素的类属性替换为样式表中的样式定义。

    我在这里所做的基本上是得到:

    1. 获取第一个样式表(您基本上可以遍历所有样式表 如果你喜欢)
    2. 循环遍历所有规则(假设所有选择器都是类 选择器)
    3. 将这些规则保存在一个对象中以便更轻松地访问它们 稍后
    4. 循环遍历所有矩形元素
    5. 获取该元素的所有类名的列表
    6. 从之前生成的映射器对象中获取每个类名的样式定义
    7. 合并这些定义
    8. 移除类属性
    9. 将样式属性值设置为从 7 开始的串联字符串。

    这样你就以 rect 元素结束,它们的类名被内联样式替换...

    P.S:: 我知道我在这里做了很多假设。要使这项工作为您工作,或者在一般情况下工作,还有很多工作要做......

    classMap = {}
    var rules = document.styleSheets[0].cssRules // 1. get first stylesheet
    for (var j = 0; j < rules.length; j++) { // 2. loop over all rules
      var selector = rules[j].selectorText
      var csstext = rules[j].cssText
      classMap[selector.replace(".", "")] = csstext.split("{")[1].replace("}", "") // 3. save class name and rule text to mapper object
    }
    
    document.querySelectorAll("rect").forEach(function(item, index) { // 4. loop over all rects
      var style = ""
      item.classList.forEach(function(className) { // 5. loop over all class names
        style += classMap[className] // 6. + 7. get style rules form mapper and concat
      })
      item.removeAttribute("class") // 8. remove class
      item.setAttribute("style", style) // 9. add inline style
      document.write("<br/>" + item.id + ": " + style)
    })
    .cl1 {
      fill: green
    }
    .cl2 {
      fill: red
    }
    .st1 {
      stroke: blue;
      stroke-width: 10
    }
    .st2 {
      stroke: orange;
      stroke-width: 5
    }
    <svg>
      <rect id="rect1" x="10" y="10" width="100" height="100" class="cl1 st1" />
      <rect id="rect2" y="10" x="150" width="100" height="100" class="cl2 st2" />
    </svg>

    另一种方法是使用getComputedStyle 来获取样式定义。这更简单,适用于一般情况,但会使您的文档很快膨胀...

    为了防止这种情况(并防止您遇到一些 chrome 错误...),您可以维护您感兴趣的所有样式属性的列表,并仅从 getComputedStyle 获取这些属性的当前值

    var props = ["fill", "stroke", "stroke-width"]
    
    document.querySelectorAll("rect").forEach(function(item, index) {
      var cstyle = getComputedStyle(item)
      props.forEach(function(prop) {
        item.setAttribute(prop, cstyle[prop])
      })
      item.removeAttribute("class")
      var X = new XMLSerializer()
      var txt = document.createTextNode(X.serializeToString(item))
      document.write("<br/><br/>")
      document.body.appendChild(txt)
    })
    .cl1 {
      fill: green
    }
    .cl2 {
      fill: red
    }
    .st1 {
      stroke: blue;
      stroke-width: 10
    }
    .st2 {
      stroke: orange;
      stroke-width: 5
    }
    <svg>
      <rect id="rect1" x="10" y="10" width="100" height="100" class="cl1 st1" />
      <rect id="rect2" y="10" x="150" width="100" height="100" class="cl2 st2" />
    </svg>

    【讨论】:

    • 谢谢,这看起来像我需要的。我会尝试这种方法
    【解决方案2】:

    你只需要将它们写成 style="height: 50px; width: 100px; background-color: blue"。这有点难以管理,因此您可能想研究另一种应用这些样式的方法,但这就是您将它们写出来的方式。

    【讨论】:

    • Ofc 我可以写,但我的 svg 会自动生成,所以我不能每次都手动添加样式
    猜你喜欢
    • 2014-06-27
    • 2018-03-06
    • 1970-01-01
    • 2019-01-02
    • 2011-04-28
    • 2011-05-30
    • 2013-06-26
    • 2015-10-02
    • 1970-01-01
    相关资源
    最近更新 更多