SVG/Tutorials/SVG und JavaScript/DOM-Scripting

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

SVG verwendet genau wie HTML das DOM (Document Object Model), bei dem Sie mit JavaScript auf jedes SVG-Element einfach zugreifen können.

Vor diesem Kapitel sollten die Themen der Kurse Einstieg in SVG und Einstieg in das DOM bekannt sein, da die dort besprochenen Methoden hier eingesetzt werden.

Inline-SVG

Wenn Sie SVG-Fragmente inline in HTML-Webseiten integrieren, sind die SVG-Elemente Teil des DOM. Sie können auf jedes SVG-Element wie auf ein beliebiges HTML-Element zugreifen.

Event-Handling

JavaScript wird im Allgemeinen beim Laden der Seite geladen und dann durch Benutzeraktionen aufgerufen. Diese Aktionen nennt man auch Events (dt. Ereignisse) .[1]


Werte mit setAttribute() ändern ansehen …
document.addEventListener('DOMContentLoaded', function () {
	function changeFill () {
		var farben = new Array(
			'red', 'skyblue', '#dfac20', '#ebf5d7','#e4ebf2', '#5a9900',
			'lime', '#df6c20', 'brown', '#5c82d9', 'burlywood',
			'blueviolet', '#c32e04', '#ffebe6' ,'#5c82d9'
		);

		var fuellFarbe = Math.floor(farben.length * Math.random());

		if (fuellFarbe == farben.length) {
			fuellFarbe = farben.length-1;
		}

		fuellFarbe = farben[fuellFarbe];
		kreis.setAttribute('fill', fuellFarbe);
	}

	document.getElementById('kreis').addEventListener('click', changeFill);
	document.getElementById('text').addEventListener('click', changeFill);
});
Der Kreis wird mit document.getElementById angesprochen und erhält mit addEventListener einen Event-Handler zugewiesen. Der Text ebenfalls, sonst passiert ausgerechnet dann nichts, wenn der Benutzer tatsächlich auf den Text (und nicht auf die Kreisfläche daneben) klickt.
Wenn nun auf den Kreis geklickt wird, wird die Funktion changeFill() aufgerufen, die nach dem Zufallsprinzip Farbwerte aus einem Array ausliest und dem Kreis mit setAttribute() zuweist.

SVG-Elemente erzeugen und löschen

Im Vergleich zu HTML wirkt die Syntax von SVG mit den vielen Geometrie-Attributen unübersichtlich. Anstatt Elemente direkt im Markup zu notieren, ist es oft vorteilhaft, diese mit aus aktuellen Berechnungen oder Eingaben ermittelten Werten dynamisch zu erzeugen.

Ellipsen erzeugen und löschen - das SVG-Markup ansehen …
<svg viewbox="0 0 880 450">

	<text x="60" y="420">Erzeuge Ellipse!</text>
	<rect id="createButton" tabindex="1" x="50" y="400" width="150" height="30" rx="5"  />

</svg>
Für die Steuerung legen wir einen Button als rect-Element an. Im Unterschied zum oberen Beispiel legen wir den Text darunter, damit wir keine doppelten EventListener benötigen, und geben dem Button eine fill-opacity: .5, damit der Text durchscheint.
Beachten Sie: Unser „Button“ ist noch kein Button, da ihm die Funktionalität fehlt. Diese wird mit tabindex="1" als XML-Attribut und cursor: pointer im CSS erreicht.
Ellipsen erzeugen - createEllipe() ansehen …
	function createEllipse(){
		svg.appendChild( getNode('ellipse', { 
			id: 'ellipse' + count,
			cx: rand(0,880), 
			cy: rand(0,400), 
			rx: 30, 
			ry: 20, 
			fill: colors[rand(0, colors.length-1)]
		}) );
		count++;
	}	
	
	function getNode(elem, v) {
		elem = document.createElementNS("http://www.w3.org/2000/svg", elem);
		for (var p in v)
			elem.setAttribute(p, v[p]);
		return elem;
	}

Die Helferfunktion getNode erzeugt aus den zwei Parametern elem und v ein neues SVG-Element. Anstelle des evtl. schon bekannten Document.createElement(), die ein HTML-Element erzeugt, wird hier die XML-Variante createElementNS() verwendet.

Die in v übergebenen Attribute werden mit ihren Werten mit elem.setAttributeNS() zugewiesen.

Ellipsen erzeugen und löschen ansehen …
function removeEllipse(event) {
	var elem = event.target; 
	if ('rect' != elem.nodeName) {
		var parent    = elem.parentNode;
		parent.removeChild(elem);
	}
}

document.querySelector('svg').addEventListener('click', removeEllipse);

Ein weiterer EventListener lauscht auf Klicks in das svg-Element. Falls das angeklickte Elemente kein rect-Element (der Button) ist, wird das Elternelement (das svg-Element) aufgerufen und dessen Kindelement mit removeChild gelöscht.

Empfehlung: Natürlich ist es möglich, svg-Elemente als Buttons, Menüs und Navigationen verwenden und sie durch tabindex und cursor entsprechend zugänglich zu machen. Einfacher ist es, …
  • SVG für die Beschreibung grafischer Inhalte zu verwenden
  • für Interaktionen die passenden HTML-Elemente mit ihrem Standardverhalten zu verwenden.

externe SVG-Dokumente ansprechen

Externes SVG-Dokument: Beispiel.svg

Eine solche Veränderung des DOMs einer SVG-Grafik ist auch bei externen SVGs möglich. Im folgenden Beispiel wird die rechts gezeigte Grafik in die Webseite eingebunden und dann mit JavaScript verändert:

mit object eingebundene SVG ansehen …
<object id="svgObject" data="Beispiel.svg" type="image/svg+xml" height="250" width="600">
  SVG-Grafik konnte nicht geladen werden!
</object>

Achtung!

Stellen Sie sicher, dass sich HTML-Datei und SVG auf dem gleichen Server befinden!

Um Cross Site Scripting (XSS) zu verhindern, unterbinden moderne Browser das Laden externer SVG-Grafiken von anderen Domains, da diese ja auch JavaScript enthalten können.
das Script ansehen …
document.addEventListener('DOMContentLoaded', function () {

	// Get the Object by ID
 	var mySVG = document.getElementById('svgObject'),
	    svgDoc;
 	// Get the SVG document inside the Object tag - Wait until it's loaded!
 	mySVG.addEventListener('load',function() {
		svgDoc = mySVG.contentDocument;
		alert('SVG contentDocument is geladen!'); 
 	}, false);	
					
	 function changeFill () {
			var svgItem = svgDoc.getElementById('quadrat');
			svgItem.setAttribute('fill', '#5a9900');	  
	}
	
	document.querySelector('#button').addEventListener('click', changeFill);

});

Wenn das im object-Element enthaltene (SVG-)Dokument und die Webseite von gleicher Herkunft sind (Same-Origin-Policy), kann man mit contentDocument auf den Inhalt des externen SVG-Dokuments zugreifen.

Die einfache Zuweisung svgDoc = mySVG.contentDocument; hat bei mir nicht funktioniert, bzw. null ergeben, da das externe Objekt beim Ausführen des Scripts noch nicht geladen war. Die anonyme Funktion, die erst nach dem Laden des Objekts feuert, stellt sicher, dass die SVG-Grafik auch wirklich zur Verfügung steht.

Anwendungsbeispiele

Weblinks

  1. W3C: Chapter 15: Scripting and Interactivity
  2. W3C: setAttributeNS