如何将 svg 对象(使用 DOMParser 从字符串创建)添加到 div 元素中?
How to add a svg-object (created with DOMParser from a string) into a div element?
我这里有 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>
您需要附加一个元素而不是文档,即
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 区分大小写。
工作代码示例:
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')
});
我这里有 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>
您需要附加一个元素而不是文档,即
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 区分大小写。
工作代码示例:
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')
});