如何将用DOMParser从字符串创建的SVG对象添加到div元素中?

3
我这里使用的是Firefox 41。
我随机从维基共享资源中获取了一个完整的SVG文件代码。 (https://upload.wikimedia.org/wikipedia/commons/c/c6/%2212_World_fly.svg)。
然后我尝试了以下两种方法将其推送到div元素中,一种是使用div的innerHTML,另一种是尝试使用div的appendChild。
innerHTML至少有效,但使用webdeveloper查看生成的HTML代码时,有些行看起来有些可疑。
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

还有显示出来。

使用appendChild根本不起作用。

我想使用类似于appendChild的东西,因为我知道使用innerHTML的解析器可能会有陷阱。

那么,如何将svg文件的完整字符串放入div中?

<html>
<head>
  <script type="application/javascript">
 function dgebi(id) {
    return document.getElementById(id);
}
// short svg file as string
var svgtext = ... //... here I added the string from https://upload.wikimedia.org/wikipedia/commons/c/c6/%2212_World_fly.svg
var d;
function init() {
    d = dgebi('id:testdiv');
    //useInnerHTMLToCreateSVG();
    useDOMParser();
}
function useInnerHTMLToCreateSVG() {
    d.innerHTML = svgtext;
}
function useDOMParser() {
// see https://developer.mozilla.org/de/docs/Web/API/DOMParser#Parsing_an_SVG_or_HTML_document
    var parser = new DOMParser();
    var doc = parser.parseFromString(svgtext, "image/svg+xml");
    // returns a SVGDocument, which also is a Document.
    d.appendChild(doc);
}    
function createElementSVG() {
    var se = document.createElement('SVG');
    d.appendChild(se);
    console.log(se);
}
</script>
</head>
<body onload="init();">
<div style="width:400px;height:400px;border: 1px #ff0000 solid;" id="id:testdiv"></div>
</body>
</html>
2个回答

5
您需要添加一个元素而不是文档,即:
d.appendChild(document.adoptNode(doc.documentElement));

在实践中,你可以省略 adoptNode。尽管它是由 w3c 强制规定的(并且由 the8472 注明为严格正确),但由于存在太多损坏的网站,浏览器不能强制使用它。
此外,你无法使用 createElement 创建 SVG 元素(它只能创建 HTML 元素)。你需要使用 createElementNS。
var se = document.createElementNS('http://www.w3.org/2000/svg', 'svg');

注意小写的名称,因为SVG区分大小写。


1
这不是一个URL,它只是一个命名空间,看起来像一个URL。W3C可能会强制你编写bibblybobblyboo来标识SVG元素,但如果他们这样做了,你可能会想知道水里有什么。 - Robert Longson
1
它提供了一个名为SVG的HTML元素。您可以像使用任何HTML元素一样使用它,尽管它没有特定的功能。 - Robert Longson
2
将一个元素从一个文档转移到另一个文档时,应该先使用document.adoptNode。大多数浏览器可能对此宽容,但并非所有浏览器都是如此。 - the8472
1
@John 这对任何当前的 UA 都没有影响。 - Robert Longson
1
没有 adoptNode,在强制执行 DOM 规范的浏览器上它将会失败。 - the8472
显示剩余6条评论

1

工作代码示例:

var renderRatingReviews = function (opts) {
    var options = opts || {},
        namespace = 'http://www.w3.org/2000/svg',
        svg = document.createElementNS(namespace, 'svg'),
        circle = document.createElementNS(namespace, 'circle'),
        arc = document.createElementNS(namespace, 'path'),
        text = document.createElement('div'),
        width = options.width || 100,
        height = options.height || 100,
        radius = width / 2,
        container = options.container,
        thickness = options.thickness || 9,
        color = options.color === 'green' ? '#00B930' : options.color === 'orange' ? '#fe9d14' : options.color === 'red' ? '#ff5534' : '#00B930',
        rating = options.rating || 8,
        polarToCartesian = function (centerX, centerY, radius, angleInDegrees) {
            var angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;
            return {
                x: centerX + (radius * Math.cos(angleInRadians)),
                y: centerY + (radius * Math.sin(angleInRadians))
            };
        },
        describeArc = function (x, y, radius, startAngle, endAngle) {
            var start = polarToCartesian(x, y, radius, endAngle),
                end = polarToCartesian(x, y, radius, startAngle),
                arcSweep = endAngle - startAngle <= 180 ? "0" : "1",
                d = [
                    "M", start.x, start.y,
                    "A", radius, radius, 0, arcSweep, 0, end.x, end.y
                ].join(" ");
            return d;
        },
        addSize = function (val) {
            return val;
        };
    if (container) {
        text.innerHTML = rating;
        text.className = 'text';
        svg.setAttribute('width', addSize(width));
        svg.setAttribute('height', addSize(height));
        circle.setAttribute('cy', addSize(height / 2));
        circle.setAttribute('cx', addSize(width / 2));
        circle.setAttribute('r', addSize(radius - (thickness / 2)));
        circle.setAttribute('stroke', '#e8e8e8');
        circle.setAttribute('stroke-width',  addSize(thickness));
        circle.setAttribute('fill', '#ffffff');
        arc.setAttribute('stroke', color);
        arc.setAttribute('stroke-width',  addSize(thickness));
        arc.setAttribute('fill', 'rgba(0, 0, 0, 0)');
        arc.setAttribute('stroke-linecap', 'round');
        arc.setAttribute('d', describeArc(width / 2, height / 2, addSize(radius - (thickness / 2)), 0, 359 * rating / 10));
        svg.appendChild(circle);
        svg.appendChild(arc);
        container.appendChild(svg);
        container.appendChild(text);
    }
}

renderRatingReviews({
    container: document.getElementById('elementId')
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接