簡短的回答是「不,在XML的世界中沒有任何等價物可以讓你給它一些標記,並讓它自動創建所有的元素和屬性在適當的名稱空間中插入的位置它。」
最接近的直接答案是@羅伯特有什麼。正如我的評論中指出的那樣,即使這樣,您仍然需要在SVG文檔中創建與您要插入片段的文檔具有相同名稱空間和前綴的片段。
相反,你可能會發現它是那麼容易(或容易)使用的便捷方法的標準DOM方法:
// Create a named SVG element on a node, with attributes and optional text
function appendTo(node,name,attrs,text){
var p,ns=appendTo.ns,svg=node,doc=node.ownerDocument;
if (!ns){ // cache namespaces by prefix once
while (svg&&svg.tagName!='svg') svg=svg.parentNode;
ns=appendTo.ns={svg:svg.namespaceURI};
for (var a=svg.attributes,i=a.length;i--;){
if (a[i].namespaceURI) ns[a[i].localName]=a[i].nodeValue;
}
}
var el = doc.createElementNS(ns.svg,name);
for (var attr in attrs){
if (!attrs.hasOwnProperty(attr)) continue;
if (!(p=attr.split(':'))[1]) el.setAttribute(attr,attrs[attr]);
else el.setAttributeNS(ns[p[0]]||null,p[1],attrs[attr]);
}
if (text) el.appendChild(doc.createTextNode(text));
return node.appendChild(el);
}
function clear(node){
while (node.lastChild) node.removeChild(node.lastChild);
}
有了這個,你可以做這樣的事情:
var icons={
Apps : "/images/apps.png",
Games : "/images/games.png"
}
var wrap = document.querySelector('#container');
clear(wrap);
for (var label in icons){
if (!icons.hasOwnProperty(label)) continue;
var icon = appendTo(wrap,'g',{'class':'icon'});
appendTo(icon,'image',{'xlink:href':icons[label]});
appendTo(icon,'text',{x:10,y:20},label);
}
這是恕我直言,比嘗試使用字符串連接構造原始SVG標記更清潔:
var svg = [];
for (var label in icons){
if (!icons.hasOwnProperty(label)) continue;
svg.push('<g class="icon">');
svg.push('<image xlink:href="'+icons[label]+'" />');
svg.push('<text x="10" y="20">'+label+'</text>');
svg.push('</g>');
}
wrap.innerSVG = svg.join(''); // doesn't work, of course
這需要片段爲有效的XML文檔(僅限單根),對嗎?而對於不具有適當名稱空間的SVG元素的片段,所創建的元素是否具有正確的名稱空間? – Phrogz 2012-03-15 18:55:59
您可能希望/需要將其包裝爲一個函數,該函數將字符串包裝到SVG根目錄中,並預定義所有通用名稱空間和前綴,然後提取內容。 – Phrogz 2012-03-15 18:57:35
是的,這個片段需要一個名稱空間屬性。 – 2012-03-15 22:32:05