På en vanlig web-side vet vi at vi kan skrive f.eks.:
var dElt=document.getElementById("her");
var echild=document.createElement("p");
echild.appendChild(document.createTextNode("heisann"));
dElt.appendChild(echild);
Vi kan gjøre helt tilsvarende i SVG, f.eks. legge til circle-elementer i et g-element.
var gElt=document.getElementById("der");
var c=document.createElement("circle");
c.setAttribute("cx",80);
c.setAttribute("cy",30);
c.setAttribute("r",20);
gElt.appendChild(c);
Dette gir ikke feil og det ser helt riktig ut når vi inspiserer elementet i browseren.
Problemet er at dette ikke har den ønskede effekten i den forstand at vi ikke ser sirkelen på webisden.
Elementet vi lager er ikke et funksjonelt svg-element, det er ikke av riktig type.
Dersom vi gjør slik fungerer det:
var gElt=document.getElementById("der");
var c = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
c.setAttribute("cx",80);
c.setAttribute("cy",30);
c.setAttribute("r",20);
gElt.appendChild(c);
Dette fungerer også siden det parses dynamisk og parseren i webbrowseren
er forberedt på å tolke svg-elementer:
var gElt=document.getElementById("der");
gElt.innerHTML+='<circle cx="80" cy="30" r="20"/>';
Vi lager oss et enkelt eksempel som vi kan bruke til å teste og demonstrere.
Vi prøver å legge til og fjerne sirkler. Strategien for å legge til sirkler
er forskjellig for røde og blå.
Røde sirkler legges til med denne koden
_addRed
var lastredcx=80;
function addRed(svgId){
// full ?
if(lastredcx >350)
return;
// find g with fill red
var gelt=document.querySelector('svg[id='+svgId+'] g[fill="red"]');
// make a circle element
// This will not work even if it produces
// the correct structure when inspected in the browser:
// var c=document.createElement("circle");
// this will work:
var c = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
c.setAttribute("cx",lastredcx+=50);
c.setAttribute("cy","30");
c.setAttribute("r","20");
// and add it
gelt.appendChild(c);
}
og fjernes med denne koden
_removeRed
function removeRed(svgId){
// find g with fill red
var gelt=document.querySelector('svg[id='+svgId+'] g[fill="red"]');
var circles=gelt.querySelectorAll('circle');
if(circles.length >0){
gelt.removeChild(circles[circles.length-1]);
lastredcx-=50;
}
}
Blå sirkler legges til med denne koden
_addBlue
var lastbluecx=80;
function addBlue(svgId){
// full ?
if(lastbluecx >350)
return;
// find g with fill blue
var gelt=document.querySelector('svg[id='+svgId+'] g[fill="blue"]');
lastbluecx+=50;
// this works since it is parsed the same way as when the page is loaded
gelt.innerHTML+='<circle cx="'+lastbluecx+'" cy="75" r="20"/>'
}
og fjernes med denne koden (som røde)
_removeBlue
function removeBlue(svgId){
// find g with fill blue
var gelt=document.querySelector('svg[id='+svgId+'] g[fill="blue"]');
var circles=gelt.querySelectorAll('circle');
if(circles.length >0){
gelt.removeChild(circles[circles.length-1]);
lastbluecx-=50;
}
}
Interaktivitet
Vi bruker det samme eksempelet og forsøker å plante
en onclick-funksjon i alle sirklene
Koden er som en kan forvente slik:
_clicking
function setClick(svgId){
//planter onclick i alle circle-elementer
var circles=document.querySelectorAll('svg[id='+svgId+'] circle');
for(var i=0;i<circles.length;i++){
circles[i].setAttribute("onclick","clicked(evt)");
}
document.getElementById("click").innerHTML=".. og click på en sirkel";
}
function clicked(evt){
target=evt.target;
// show what we have hit
document.getElementById("msg").innerHTML=
target.parentNode.getAttribute("fill")+
" : x="+target.getAttribute("cx");
// admin own fill-attribute in circle
if(target.getAttribute("fill")=="black")
target.setAttribute("fill",target.parentNode.getAttribute("fill"));
else
target.setAttribute("fill","black");
}
AJAX
Så langt har vi sett at SVG-elementet føyer seg pent inn i DOMen på webside,
untatt når vi skal legge til nye elementer inne i SVG-elementet.
Vi skal se litt på hvordan vi kan hente SVG-elementer ved hjelp av AJAX.
Vi bruker det samme eksempelet som råmateriale. Vi legger to varaianter på fil
function doSVGX(){
$.ajax({
url:"demo.xml",
success:function(data,status,xhr)
{
useSVGX(xhr.responseXML);
},
error:function(data)
{
document.getElementById("dumpX").innerHTML
=data.statusText;
}
});
}
function useSVGX(svgdoc){
var elt=document.getElementById("dumpX");
// clear it (for second call)
elt.innerHTML="";
// forutsetter at svg har correct header: version and namespace
var svgNode=svgdoc.documentElement;
elt.appendChild(document.importNode(svgNode, true));
}