Erreiche, was du erreichen willst
Für unerfahrene JavaScript-Entwickler ist HTML ein Spielplatz:
HTML: <a href="index.html" onmouseover="image1.src='1on.gif'" onmouseout="image1.src='1off.gif'"> <img src="1off.gif" name="image1" border="0" height="150" width="150" alt="Anfangsseite"></a>
Die etwas erfahreneren gehen nicht ganz so weit:
HTML: <a href="index.html" onmouseover="roll('home',1)" onmouseout="roll('home',0)"> <img src="home.gif" name="home" border="0" height="150" width="150" alt="Anfangsseite"></a> JavaScript: // Bilder vorladen homeoff = new Image(); homeoff.src = 'home.gif'; homeon = new Image(); homeon.src = 'homeoff.gif'; function roll(imgName,a) { imgState=a==0?eval(imgName + 'on.src'):eval(imgName + 'off.src'); document.images[imgName].src = imgState; }
Egal wie, wenn wir JavaScript Aufrufe im HTML einbinden, erschweren wir zukünftige Änderungen: Falls sich der Name der Funktion ändert, muß jedes HTML Dokument umgeschrieben werden. Ausserdem erstellen wir eine Menge Code für jeden einzelnen Bildwechsel, und vergrößern dadurch unnötigerweise das Dokument.
Hinfort! ihr JavaScript Geister!
Vergessen wir einen Augenblick lang dass fast jeder Bildwechseleffekt heutzutage per CSS erstellt werden kann, und nehmen wir an dass unser HTML unveränderbar das Folgende ist:
HTML: <a href="index.html"><img src="home.gif" id="home" alt="Anfangsseite"></a>
Wie können wir einen Bildwechsel hervorrufen wenn die Maus sich über dem Bild befindet?
Kletterurlaub im Dokument
Jedes XML Dokument (und das
beinhaltet HTML), hat eine
bestimmte Baumstruktur. Ein Knoten (node) ist Teil dieses Baumes - genauso wie ein
Dokument oder ein Verzeichnis im Windows Explorer ein Teil der Festplatte ist.
Es gibt zwölf verschiedene Arten von Knoten[1]. In HTML
sind allerdings nur drei wirklich interessant: element
,
TextNode
und AttributeNode
. Das Erste sind Seitenelemente,
wie ein Verweis, das Zweite der Text innerhalb des Verweises und das Dritte zum
Beispiel die Adresse, auf die der Verweis zeigt.
Unsere Kletterausrüstung
Wie haben mehrere Methoden und Attribute zur Verfügung, um uns durch das Dokument zu hangeln.
Methoden um ein bestimmtes Element zu erreichen
getElementById('elementID')
- gibt uns das Element mit der ID
elementID
als einObjekt
. getElementsByTagName('tag')
- gibt uns alle Elemente mit dem Namen
tag
als einArray
.
Wir können diese nach Belieben mischen. Zum Beispiel:
document.getElementById('navigation').getElementsByTagName('a')[3]; gibt uns den vierten Verweis innerhalb des Elements mit der ID 'navigation' document.getElementsByTagName('div')[2].getElementsByTagName('p')[0]; gibt uns den ersten Textabsatz innerhalb des dritten DIV Elements
Attribute - unser Kletterwerkzeug
childNodes
- gibt uns alle Knoten, die von dem abzweigen auf den wir uns gerade befinden, als
Array
. Es gibtfirstChild
undlastChild
, als Abkürzungen fürchildNodes[0]
undchildNodes[this.childNodes.length-1]
. parentNode
- ist der Knoten von dem der derzeitige abzweigt.
nextSibling
- ist der nächste Knoten auf der gleichen Ebene wie der, auf dem wir uns befinden.
previousSibling
- der vorherige Knoten auf der gleichen Ebene wie der, auf dem wir uns befinden.
Auch diese Attribute können nach Belieben und Notwendigkeit gemischt werden.
JavaScript:
var other=document.getElementById('nav').childNodes[3].firstChild;
gibt uns den ersten Knoten des vierten Knotens innerhalb
des Elements mit der ID 'nav'.
var prevlink=o.parentNode.previousSibling.firstChild.childnodes[2];
gibt uns den dritten Knoten innerhalb des ersten Knotens
des vorherigen Knotens auf der gleichen Ebene wie das
Objekt o
.
Attribute und Methoden um Elemente zu verändern
attributes
- gibt uns ein Array mit allen Attributen des derzeitigen Elements zurück. Microsoft Internet Explorer unterstützt dieses Attribut erst seit Version 6.0.
data
- gibt uns oder setzt den Textinhalt des Knotens
nodeName
- gibt uns den Namen des Knotens, z.B. 'INPUT'
nodeType
- gibt uns die Art des Knotens — 1 is ein Element, 2 ein Attribut und 3 Text.
nodeValue
- gibt uns oder setzt den Wert des Knotens. Dieser Wert ist der Textinhalt
bei Textknoten, das Attribut bei Attributknoten und
null
bei Elementen. getAttribute(attribute)
- gibt uns den Wert des Attributs
attribute
.
JavaScript: var other=document.getElementById('nav').firstChild; if(other.nodeType==3) { other.data='newtext'; } if(other.nodeType==1) { other.firstChild.data='newtext'; }
Um das Bild in unserem Beispiel zu erreichen können wir entweder
getElementsByTagName
oder getElementById
verwenden.
HTML: <a href="index.html"><img src="home.gif" id="home" alt="home"></a> JavaScript: function findimg() { var image; image=document.getElementById('home'); if (image) { image.style.border='3px dashed #ccc'; } } oder: function findimg() { var imgs,i; imgs=document.getElementsByTagName('img'); for(i in imgs) { if(/home.gif/.test(imgs[i].src)) { imgs[i].style.border='3px dashed #ccc'; } } }
Die Verwendung von getElementById
ist einfacher, da wir nicht
durch alle Elemente gehen müssen um unseres zu finden. Wenn wir getElementsByTagName
verwenden, brauchen wir ein Erkennungsmerkmal um unser Bild zu erreichen. In diesem Fall
welches Bild geladen werden soll. Eine herkömlichere Art und
Weise ist es auf eine bestimmte Klasse zu prüfen.
HTML: <a href="index.html"><img src="home.gif" class="roll" alt="home"></a> JavaScript: function findimg() { var imgs,i; imgs=document.getElementsByTagName('img'); for(i in imgs) { if(/roll/.test(imgs[i].className)) { imgs[i].style.border='3px dashed #ccc'; } } }
Was wir jetzt benötigen ist eine Funktion, die den Bildwechseleffekt hervorruft, und die nötigen Aufrufe hinzufügt.
function findimg() { var imgs,i; // gehe durch alle Bilder im Dokument imgs=document.getElementsByTagName('img'); for(i=0;i<imgs.length;i++) { // überprüfe ob die Klasse 'roll' vorhanden ist if(/roll/.test(imgs[i].className)) { // rufe die Funktion roll() auf wenn der Mauszeiger über // dem Bild ist und wenn er es verlässt. Übergebe // das Bild als Objekt. imgs[i].onmouseover=function(){roll(this);}; imgs[i].onmouseout=function(){roll(this);}; } } } function roll(o) { var src,ftype,newsrc; // überpfrüfe, on der Verweis des Bildes schon ein _on beinhaltet // oder nicht. src = o.src; ftype = src.substring(src.lastIndexOf('.'), src.length); if(/_on/.test(src)) { // falls dem so ist, lösche das _on. newsrc = src.replace('_on',''); }else{ // anderweitig, füge das _on hinzu newsrc = src.replace(ftype, '_on'+ftype); } o.src=newsrc; } window.onload=function(){ findimg(); } Probier dieses Beispiel aus
So weit, so gut. Was wir allerdings vergessen haben sind Besucher, die keine Maus benutzen können. Um ebenfalls diese Besucher zu erreichen, müssen wir überprüfen ob der Verweis in dem das Bild sich befindet derzeit den Fokus hat oder nicht. Das Bild selbst ist per Tastatur nicht erreichbar.
Um den Verweis zu erreichen, können wir das parentNode
Attribut
überprüfen. Das ändert allerdings auch das Objekt, das wir an die
roll()
Funktion übergeben.
Daher müssen wir das Bild nochmals finden indem wir durch die Knoten
innerhalb des Verweises gehen. Wir prüfen, ob der Knoten ein Bild ist indem wir nodeType
und nodeName
überprüfen. Das ist notwendig, da manche
Webbrowser Leerzeilen im Dokument als Knoten erkennen, andere aber nicht.
function findimg() { var imgs,i; // gehe durch alle Bilder im Dokument // überprüfe ob die Klasse 'roll' vorhanden ist imgs=document.getElementsByTagName('img'); for(i=0;i<imgs.length;i++) { if(/roll/.test(imgs[i].className)) { // füge die Funktion roll() dem übergeordneten // Knoten hinzu. imgs[i].parentNode.onmouseover=function(){roll(this);}; imgs[i].parentNode.onmouseout=function(){roll(this);}; imgs[i].parentNode.onfocus=function(){roll(this);}; imgs[i].parentNode.onblur=function(){roll(this);}; } } } function roll(o) { var i,isnode,src,ftype,newsrc,nownode; // gehe durch alle Kindknoten for (i=0;i<o.childNodes.length;i++) { nownode=o.childNodes[i]; // falls der Knoten ein Bild ist, stoppe die Schleife und // definiere eine Variable if(nownode.nodeType==1 && /img/i.test(nownode.nodeName)) { isnode=i; break; } } // teste den Verweis des Bildes und fuege den Bildwechsel- // effekt hinzu. src = o.childNodes[isnode].src; ftype = src.substring(src.lastIndexOf('.'), src.length); if(/_on/.test(src)) { newsrc = src.replace('_on',''); }else{ newsrc = src.replace(ftype, '_on'+ftype); } o.childNodes[isnode].src=newsrc; } window.onload=function(){ findimg(); } Probiere dieses Beispiel mit der Tastatur aus.
Selbstversuche
Lade das das HTML Beispiel herunter und versuche Dich sich an einer der folgenden Aufgaben. Folge den Lösungsverweisen um eine mögliche Lösung zu sehen. Die Lösungsbeispiele beinhalten das notwendige JavaScript , was zwar nicht mit den Grundsätzen des barrierefreien JavaScripts übereinstimmt, aber einfacher zu lesen und verstehen ist.
- Ändere die Farbe einer jeden
H2
Überschrift nach blau um. Lösung Farbänderung. - Markiere jeden zweiten Paragraph mit einem schwarzen Rand. Lösung Randparagraph.
- Überprüfe welcher der Verweise im Dokument zu einem anderen
Server führt (indem du prüfst ob in dem
href
Attribut die derzeitige Seite vorkommt - die derzeitige Seite ist inwindow.location.hostname
gespeichert) und schreibe das Ziel des Verweises innerhalb von Klammern hinter den Verweis. Für den Moment, ändere den Inhalt des Links mittels desinnerHTML
Attributs des Verweises. Lösung Fremdverweise. - Füge einen
onclick
Befehl zu jedem Verweis hinzu, der das Attributtarget
aufweist. Öffne den Verweis in einem 400 mal 400 Pixel großen Pop-Up Fenster. Lösung Pop-Up.
Verweise
[1] DOM Knotentypen: http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ core.html#ID-1950641247