假设:

<html>
<head>
 <script type="text/javascript" src="jquery.js"></script>
 <script type="text/javascript">
 $(document).ready(function(){
  $("svg").append('<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>');
 });
 </script>
</head>
<body>
 <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">
 </svg>
</body>

为什么我什么都看不到?


当前回答

替代方案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(取决于正确的名称空间)元素。

使用前面提到的变通方法也可以解决这个问题。

其他回答

JQuery不能将元素附加到<svg>(它似乎在DOM资源管理器中添加了它们,但不在屏幕上)。

一种解决方法是在页面中附加一个<svg>和所有需要的元素,然后使用.attr()修改元素的属性。

$('body')
  .append($('<svg><circle id="c" cx="10" cy="10" r="10" fill="green" /></svg>'))
  .mousemove( function (e) {
      $("#c").attr({
          cx: e.pageX,
          cy: e.pageY
      });
  });

http://jsfiddle.net/8FBjb/1/

如果需要追加的字符串是SVG,并且添加了适当的名称空间,则可以将字符串解析为XML并追加到父对象。

var xml = jQuery.parseXML('<circle xmlns="http://www.w3.org/2000/svg" cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>');
$("svg").append(xml.documentElement)
 var svg; // if you have variable declared and not assigned value.
 // then you make a mistake by appending elements to that before creating element    
 svg.appendChild(document.createElement("g"));
 // at some point you assign to svg
 svg = document.createElementNS('http://www.w3.org/2000/svg', "svg")
 // then you put it in DOM
 document.getElementById("myDiv").appendChild(svg)
 // it wont render unless you manually change myDiv DOM with DevTools

// to fix assign before you append
var svg = createElement("svg", [
    ["version", "1.2"],
    ["xmlns:xlink", "http://www.w3.org/1999/xlink"],
    ["aria-labelledby", "title"],
    ["role", "img"],
    ["class", "graph"]
]);
function createElement(tag, attributeArr) {
      // .createElementNS  NS is must! Does not draw without
      let elem = document.createElementNS('http://www.w3.org/2000/svg', tag);             
      attributeArr.forEach(element => elem.setAttribute(element[0], element[1]));
      return elem;
}
// extra: <circle> for example requires attributes to render. Check if missing.

一个更简单的方法是将SVG生成为字符串,创建包装器HTML元素,并使用$(“#wrapperElement”). HTML (svgString)将SVG字符串插入到HTML元素中。这在Chrome和Firefox中工作得很好。

替代方案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(取决于正确的名称空间)元素。

使用前面提到的变通方法也可以解决这个问题。