替代方案1:原生js insertAdjacentHTML()
如果你根本不考虑切换到原生JavaScript……
您还可以使用本地javaScript方法insertAdjacentHTML()来获得同样方便的表示法。
$("#svg")[0].insertAdjacentHTML(
"beforeEnd",
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
);
$("#svg")[0]使你的jQuery对象在原生JS中可选。
替代方案2:编写一个原生js DOMParser()帮助器
mdn web文档:DOMParser.parseFromString()
function createSvgEl(markup) {
markup = `<svg xmlns="http://www.w3.org/2000/svg">
${markup}</svg>`;
const svgEl = new DOMParser().parseFromString(markup, "image/svg+xml")
.documentElement.children[0];
return svgEl;
}
jQuery的用法:
$("#svgXML").append(
createSvgEl(
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
)
);
Demo
// native js helper
function createSvgEl(markup) {
markup = `<svg xmlns="http://www.w3.org/2000/svg">
${markup}</svg>`;
const svgEl = new DOMParser().parseFromString(markup, "image/svg+xml")
.documentElement.children[0];
return svgEl;
}
$(document).ready(function() {
// works - but will remove existing children
$("#svg1").html(
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
);
// works
// $("#svg")[0] makes your jQueryObject selectable in native JS
$("#svg")[0].insertAdjacentHTML(
"beforeEnd",
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
);
$("#svgXML").append(
createSvgEl(
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
)
);
// jquery still works! Vanilla doesn't harm!
$("#svgXML circle:nth-of-type(2)").attr('fill', 'orange');
//insert after()
$("#svgAfter circle").after(
createSvgEl(
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
)
);
//insert after native
$("#svgAfterNative circle")[0].insertAdjacentHTML(
"afterEnd",
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
);
});
svg {
border: 1px solid red;
overflow: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Append via native js insertAdjacentHTML()</p>
<svg id="svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
<circle cx="10" cy="10" r="5" fill="green" />
</svg>
<p>Append via DOMParser() helper</p>
<svg id="svgXML" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
<circle cx="10" cy="10" r="5" fill="green" />
</svg>
<p>Append via jquery html() - will strip existing child nodes</p>
<svg id="svg1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
<circle cx="10" cy="10" r="5" fill="green" />
</svg>
<p>Insert after existing element with jQuery after() using DOMParser() helper</p>
<svg id="svgAfter" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
<circle cx="10" cy="10" r="5" fill="green" />
</svg>
<p>Insert after existing element with native js insertAdjacentHTML()</p>
<svg id="svgAfterNative" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
<circle cx="10" cy="10" r="5" fill="green" />
</svg>
jquery的after()或before()方法也将无法添加SVG DOM(取决于正确的名称空间)元素。
使用前面提到的变通方法也可以解决这个问题。