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

How to add a data-* attribute to svg on or after creation

我有一个 canvas,我正在使用 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)
}

这让我可以看到文件的更多细节,但我还是不知道如何在调用 saveAs.

之前保存 data-settings 属性

如有任何帮助,我们将不胜感激。谢谢

最好用 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);
}