Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将SVG图像动态插入HTML?_Javascript_Html_Ajax_Svg - Fatal编程技术网

Javascript 如何将SVG图像动态插入HTML?

Javascript 如何将SVG图像动态插入HTML?,javascript,html,ajax,svg,Javascript,Html,Ajax,Svg,我有一些代码可以通过Ajax从服务器检索脚本svg图像。我可以将图像文本返回到浏览器中,但我找不到将其插入到实际显示它的DOM中的方法。有人能帮忙吗? svg如下所示: <svg id="chart" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)"> <script type="application/ecmascript">

我有一些代码可以通过Ajax从服务器检索脚本svg图像。我可以将图像文本返回到浏览器中,但我找不到将其插入到实际显示它的DOM中的方法。有人能帮忙吗? svg如下所示:

<svg id="chart" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)">
<script type="application/ecmascript">
<![CDATA[
...lots of code, changes on each Ajax request
//]]>
</script>
<script type="application/ecmascript" xlink:href="js-on-server-1.js"/>
<script type="application/ecmascript" xlink:href="js-on-server-2.js"/>
</svg>
然后Opera和Chrome什么也不做,F/F抱怨“[object XMLDocument]”。如果我将“responseXML”更改为“responseText”,则Opera/Chrome会在正确的位置正确显示整个svg文本(而不是图像),而F/F仍会给出相同的警告。 我还尝试将响应分配给innerHTML,但这没有任何作用。 有什么想法吗?谢谢

编辑

为了回应下面的Phrogz'z回答,我添加了两个简单的svg文件。第一个是一个“标准”的简单svg,显示一个圆圈。第二个是脚本svg,显示一个矩形。除了IE8-,您应该能够在任何浏览器中直接查看两者。 如果我编辑Phrogz'z代码以使用圆形文件(将“stirling4.svg”替换为该文件的名称),那么它可以工作,但是如果我想要脚本化的矩形,它就不能工作。在F/F、Opera、Chromium上测试,但在(我的)Chromium上无论如何都不起作用

文件1,圆圈:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
</svg>

文件2,矩形:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)">
<script type="application/ecmascript">
<![CDATA[
var svgDocument;
var svgns = "http://www.w3.org/2000/svg";
function init(evt) {
  if(window.svgDocument == null)
    svgDocument = evt.target.ownerDocument;
   var lbox = svgDocument.createElementNS(svgns, "rect");
   lbox.setAttributeNS(null, "x",                10);
   lbox.setAttributeNS(null, "y",                10);
   lbox.setAttributeNS(null, "width",            30);
   lbox.setAttributeNS(null, "height",           30);
   lbox.setAttributeNS(null, "stroke",           "#8080ff");
   lbox.setAttributeNS(null, "stroke-width",     2);
   lbox.setAttributeNS(null, "fill-opacity",     0);
   lbox.setAttributeNS(null, "stroke-opacity",   1);
   lbox.setAttributeNS(null, "stroke-dasharray", 0);
   svgDocument.documentElement.appendChild(lbox);
}
//]]>
</script>
</svg>


答案大概是将脚本放入标题中???

一般来说,问题有两个方面:

  • HTML不是XHTML,在撰写本文时,HTML中对SVG的支持是不完善的,而且定义也很差。解决方案是使用真正的XHTML文档,其中SVG名称空间的元素实际上被视为SVG

  • responseXML
    位于另一个DOM文档中,通常不能将节点从一个文档移动到另一个文档。应该使用将节点从一个文档导入到另一个文档

  • 使用
    onload
    事件处理程序加载SVG文件不会通过创建节点或将其附加到文档中来调用这些处理程序。但是,script块中的代码将被运行,因此您需要以一种独立工作的方式重写脚本,同时也可以使用动态加载


  • 下面是一个在Chrome、Safari和Firefox中工作的简单示例……但不是IE9:

    var xhr=newxmlhttprequest;
    open('get','stirling4.svg',true);
    xhr.onreadystatechange=函数(){
    如果(xhr.readyState!=4)返回;
    var svg=xhr.responseXML.documentElement;
    svg=document.importNode(svg,true);//在这些浏览器中是可选的
    document.body.appendChild(svg);
    };
    xhr.send();
    
    请在此处查看它的实际操作:


    不幸的是,IE9不能正确支持
    document.importNode
    。为了解决这个问题,我们编写了自己的
    cloneToDoc
    函数,通过递归地对层次结构进行爬网,为任何给定节点创建一个等效结构。下面是一个完整的工作示例:

    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head> 
      <meta http-equiv="content-type" content="application/xhtml+xml;charset=utf-8"/>
      <title>Fetch and Include SVG in XHTML</title>
      <script type="text/ecmascript"><![CDATA[
        setTimeout(function(){
          var xhr = new XMLHttpRequest;
          xhr.open('get','stirling4.svg',true);
          xhr.onreadystatechange = function(){
            if (xhr.readyState != 4) return;
            var svg = cloneToDoc(xhr.responseXML.documentElement);
            document.body.appendChild(svg);
          };
          xhr.send();
        },1000);
        function cloneToDoc(node,doc){
          if (!doc) doc=document;
          var clone = doc.createElementNS(node.namespaceURI,node.nodeName);
          for (var i=0,len=node.attributes.length;i<len;++i){
            var a = node.attributes[i];
            if (/^xmlns\b/.test(a.nodeName)) continue; // IE can't create these
            clone.setAttributeNS(a.namespaceURI,a.nodeName,a.nodeValue);
          }
          for (var i=0,len=node.childNodes.length;i<len;++i){
            var c = node.childNodes[i];
            clone.insertBefore(
              c.nodeType==1 ? cloneToDoc(c,doc) : doc.createTextNode(c.nodeValue),
              null
            ); }
          return clone;
        }
      ]]></script>
    </head><body></body></html>
    
    使用脚本.xhtml导入svg

    
    在XHTML中获取并包含脚本SVG
    
    Try:
    addImage(xmlhttp.response,“某处”)?html文档的哪种内容类型:text/html、application/xhtml+xml?您试图将SVG插入的documentElement的doctype和属性是什么?(1)测试页面最初没有文档或内容类型。我现在为XHTML1.0和XHTML1.1添加了doctype,没有任何更改。(2) 我还尝试了显式text/html和application/xhtml+xml,没有任何改变。(3) 我刚刚尝试了“xmlhttp.response”:F/F没有变化,但是Chrome&Opera现在说输出“未定义”,而不是svg文本。(4) 我正在将SVG插入一个空范围:。谢谢。我开始认为我需要将其理解为XML(responseXML)、importNode,然后是appendChild。我会在一段时间内尝试一下……这里有一个简单的例子。我将很快为您创建一个SVG到HTML示例。我无法在Chrome(8.0.552.237(70801)Ubuntu10.10)上运行这个程序-你确定在Chrome上可以吗?下一个问题更棘手——它不适用于脚本svg。我在我的原始帖子中添加了两个示例来替换您的“stirling4.svg”。谢谢。@user785194是的,这两个示例在Chrome v15中都能很好地工作。我将研究如何加载一个直接在脚本中创建内容的SVG。我假设问题是您正在使用
    onload
    属性来触发脚本,而这不会触发。此外,当您说“我无法在Chromium上运行此功能”时,最好包含详细信息。会发生什么?您看到控制台中有任何错误吗?@Phrogz我们有没有可能得到关于这个答案的更新,因为它的浏览量相对较高,而且似乎过时了?@Zachsauier仅仅因为它旧了并不意味着它过时了。:)你会包括哪些新信息?请注意,堆栈溢出类似于wiki,并鼓励用户改进现有答案。
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head> 
      <meta http-equiv="content-type" content="application/xhtml+xml;charset=utf-8"/>
      <title>Fetch and Include SVG in XHTML</title>
      <script type="text/ecmascript"><![CDATA[
        setTimeout(function(){
          var xhr = new XMLHttpRequest;
          xhr.open('get','stirling4.svg',true);
          xhr.onreadystatechange = function(){
            if (xhr.readyState != 4) return;
            var svg = cloneToDoc(xhr.responseXML.documentElement);
            document.body.appendChild(svg);
          };
          xhr.send();
        },1000);
        function cloneToDoc(node,doc){
          if (!doc) doc=document;
          var clone = doc.createElementNS(node.namespaceURI,node.nodeName);
          for (var i=0,len=node.attributes.length;i<len;++i){
            var a = node.attributes[i];
            if (/^xmlns\b/.test(a.nodeName)) continue; // IE can't create these
            clone.setAttributeNS(a.namespaceURI,a.nodeName,a.nodeValue);
          }
          for (var i=0,len=node.childNodes.length;i<len;++i){
            var c = node.childNodes[i];
            clone.insertBefore(
              c.nodeType==1 ? cloneToDoc(c,doc) : doc.createTextNode(c.nodeValue),
              null
            ); }
          return clone;
        }
      ]]></script>
    </head><body></body></html>