如何在创建时或创建后向svg添加data- *属性

时间:2017-11-17 04:29:18

标签: javascript svg blob filesaver.js

我有一个画布,我正在使用FileSaver.js api创建快照并保存和下载为svg。 svg永远不会被渲染到应用程序,它会在创建后直接下载。

我的问题是,我需要在自定义data-*标记的svg中添加一些设置。我无法弄清楚这需要发生的方式和地点。一旦我有blob,在我调用saveAs之前或之后?但后来如何获得它的参考。以下是我到目前为止所尝试的内容。

_onExportFrame() {
            var settings = this.settings;
            var svgBlob = new Blob([this.getFrame()], {type: "image/svg+xml;charset=utf-8"});
            saveAs(svgBlob, "snapshot.svg");
}

以上创建和下载svg非常好,但我无法弄清楚如何添加自定义数据设置属性。我还尝试过首先创建一个文件,如下所示

_onExportFrame() {
        var settings = this.settings;
        var svg = new File([this.getFrame()], "snapshot.svg", {type: "image/svg+xml;charset=utf-8"});
        saveAs(svg)
}

允许我查看该文件的更多详细信息,但在调用data-settings之前,我无法确定如何保存saveAs属性。

任何帮助都会非常感激。感谢

1 个答案:

答案 0 :(得分:2)

最好的方法是使用this.getFrame()方法 在将序列化返回到字符串之前,此方法肯定会创建一个已解析的SVG文档 从这个解析的SVG文档中,您将添加此属性。

getFrame

的推测部分内容
getFrame: function() {
  var svg = document.createElementNS(svgNS, 'svg');
  svg.dataset.settings = your_data; // here you set the data attribute
  // ... append a lot of elements to svg to generate the svg image
  // ...
  return new XMLSerializer().serializeToString(svg); // return the markup
}

现在,既然你没有提供这种getFrame方法,我会假设你没有做到这一点,并且你可能很难调整它。

所以,在你获得标记之后,一种方法是重新解析这个标记,添加你的属性,然后再重新序列化......



var svgStr = /*this.*/getFrame(); // get the markup
// (re-)parse this string as an SVG doc
var svgDoc = new DOMParser().parseFromString(svgStr, 'image/svg+xml');
// set your attribute
svgDoc.documentElement.dataset.settings = "foo-bar";
// re-serialize
svgStr = new XMLSerializer().serializeToString(svgDoc.documentElement);
// save the modified markup
saveAs(new Blob([svgStr], {type:'image/svg+xml'}));



function getFrame(){
  return `<svg width="120" height="120" viewBox="0 0 120 120"
    xmlns="http://www.w3.org/2000/svg">
  <rect x="10" y="10" width="100" height="100"/>
  <script>
  alert(document.documentElement.dataset.settings);
  <\/script>
</svg>`
}
// for demo displays in an <object> instead of saving
function saveAs(blob){
  var obj = document.createElement('object');
  obj.data=  URL.createObjectURL(blob);
  document.body.appendChild(obj);
}
&#13;
&#13;
&#13;