2011-05-20 37 views
3

我無法用Javascript編寫內聯SVG。
的問題可以歸納爲以下的代碼(live example here):SVG片段被錯誤地解析爲HTMLUnknownElement

某處體內:

<svg id="drawing" xmlns="http://www.w3.org/2000/svg" version="1.1"> 
</svg> 

內onReady:

$("#drawing").append($("<rect style='fill: blue' width='100' height='100' />")); 

我希望現在看到一個藍色的矩形。但是,Chrome和Firefox不顯示任何內容。

使用Firebug,我發現Firefox將「rect」解釋爲HTMLUnknownElement(而不是SVGElement)。
如果我在SVG元素(使用Firebug)上選擇「編輯SVG」並在某處插入空格,SVG似乎會被重新整理並出現矩形。

我該如何告訴解析器正確解析這個片段?

+1

你試過在rect上顯式命名空間嗎?或者,您可以通過編程創建節點並插入它嗎? – Marcin 2011-05-20 17:05:53

+0

你的意思是像http://jsfiddle.net/Jkjaa/3/?不,也行不通。 好吧 - 我從GET請求中獲取SVG片段作爲文本。我想避免手動解析它。 – Matthias 2011-05-20 17:15:33

+0

那個jsFiddle對我沒有幫助。另外,我不明白它是如何實現這兩個建議的。 – Marcin 2011-05-20 17:18:57

回答

1

恐怕不是那麼容易:

  1. 的jsfiddle不是測試SVG的地方,它發送錯誤的內容類型
  2. 引用外部JS-文件無法創建的HTML (永遠記住,svg不需要用html做任何事情)
  3. jquery在使用append()時使用一些虛擬div創建元素,但svg不知道div元素
  4. 還要注意:使用jQuery綁定到svg文檔的加載事件似乎不起作用

下面的示例代碼,當作爲交付對我的作品在FF圖像/ SVG + XML


<svg id="drawing" 
    xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    version="1.1" 
    onload="fx()"> 
    <script type="text/ecmascript" xlink:href="http://code.jquery.com/jquery-latest.js" /> 
    <script type="text/ecmascript"> 
    function fx() 
    { 
    $(document.createElementNS('http://www.w3.org/2000/svg', 'rect')) 
    .css('fill','blue') 
    .attr({'width':100,'height':100}) 
    .appendTo('#drawing'); 
    } 
    </script> 
</svg> 

但是就像馬辛我會建議使用插件。

從父文檔添加則可以使用含有該元素的屬性的對象,基本的例子:


<html> 
<head> 
<script src="http://code.jquery.com/jquery-latest.js"></script> 
<script type="text/javascript"> 
/*<![CDATA[*/ 

function fx(obj,params) 
{ 
    var svgDoc=obj.contentDocument; 
    if(typeof params.name!='string')return; 
    var props=$.extend({'attrs':{},'style':{},'selector':null},params); 
     props.target=(!props.selector)?svgDoc.documentElement:$(svgDoc).find(props.selector) 

    $(svgDoc.createElementNS('http://www.w3.org/2000/svg', props.name)) 
    .css(props.style) 
    .attr(props.attrs) 
    .appendTo(props.target); 
} 

/*]]>*/ 
</script> 
</head> 
<body> 
    <object onload="fx(this,{'name':'rect','attrs':{'width':100,'height':100},'style':{'fill':'blue'},'selector':'#drawing'})" 
      data="my.svg" 
      type="image/svg+xml" 
      width="200" 
      height="200"> 
    <param name="src" value="my.svg"> 
    </object> 
</body> 
</html> 

的對象的結構:

  • name:tagName(string)
  • 個ATTRS:屬性(對象)
  • 樣式:樣式(對象)
  • 選擇:選擇器(字符串,如果省略了根元素將被選擇)
+0

我不想使用獨立的SVG,但將其嵌入到HTML中。但是,應該動態加載SVG的某些部分。有關如何運輸和解析它們的想法?根據你的回答,將它們作爲明文發送的方法似乎不起作用。是否真的不可能以某種方式解析SVG片段? – Matthias 2011-05-20 19:13:01

+0

增加了另一個例子,也許它很有用。 – 2011-05-20 22:52:17

1

該實施例顯示瞭如何在XHTML嵌入SVG包括編程創建新的SVG元素:http://phrogz.net/svg/svg_in_xhtml5.xhtml

此示例說明如何使用XHR將SVG提取爲XML,查找其中的一個片段,並使用兩種方式將它轉換爲本地文檔,然後再將該節點附加到現有SVG文檔:http://phrogz.net/svg/fetch_fragment.svg

一般情況下:

  1. 不要直接使用jQuery與SVG。
  2. 動態創建的SVG元素必須使用createElementNS創建,並提供SVG名稱空間URI 'http://www.w3.org/2000/svg'。 (但是,請注意,不應使用名稱空間創建SVG屬性。)
  3. 您需要確保將您的XHTML作爲XML(content-type:application/xhtml + xml)而不是text/html。

下面是我常用的一個通用函數,可以方便地創建SVG元素。它既可以在SVG文檔中使用,也可以在SVG-in-XHTML中使用,允許直接創建文本內容,並支持命名空間屬性(如xlink:href)。

// Example usage: 
// var parentNode = findElementInTheSVGDocument(); 
// var r = createOn(parentNode, 'rect', { 
//  x:12, width:10, height:10, 'fill-opacity':0.3 
// }); 
function createOn(root,name,attrs,text){ 
    var doc = root.ownerDocument; 
    var svg = root; 
    while (svg.tagName!='svg') svg=svg.parentNode; 
    var svgNS = svg.getAttribute('xmlns'); 
    var el = doc.createElementNS(svgNS,name); 
    for (var attr in attrs){ 
    if (attrs.hasOwnProperty(attr)){ 
     var parts = attr.split(':'); 
     if (parts[1]) el.setAttributeNS(svg.getAttribute('xmlns:'+parts[0]),parts[1],attrs[attr]); 
     else el.setAttributeNS(null,attr,attrs[attr]); 
    } 
    } 
    if (text) el.appendChild(document.createTextNode(text)); 
    return root.appendChild(el); 
} 
0

我想你想獲得解析SVG的片段,而不必把它變成JSON和諸如此類的東西。這是一些CoffeeScript的功能。我測試了嵌入在HTML中的SVG代碼,但我認爲它應該可以在任何情況下工作。

https://github.com/pwnall/ddr/blob/master/javascripts/graphics/pwnvg.coffee#L169

我包裹SVG片段在標籤建立一個獨立的SVG文件,然後我用的DOMParser來解析SVG文件,我拔出根元素的兒童(包裝),並將它們粘貼到原始SVG的DOM中。

從理論上講,有一種更容易(更快的方法),但現在不起作用。 http://crbug.com/107982