Webtechnologien. Teil 13: JavaScript Document Object Model (DOM)

Ähnliche Dokumente
Webtechnologien. Teil 12: JavaScript Document Object Model (DOM)

DOM Document Object Model

Webtechnologien. Teil 13: JSON und etwas AJAX

Inhaltsverzeichnis. Florian Bauer CSS Seite 2 von 10

JavaScript clientseitige Programmiersprache zur Dynamisierung von Internetseiten

1 Definition der Selektoren Einbinden der CSS 3 Möglichkeiten Farbangaben Schriftformatierung Abstände...

Allgemeine Technologien II Sommersemester Mai 2011 CSS

Funktionen nur wenn dann

PDF. PDF-Generierung aktivieren. Methode zum Erzeugen der PDFs. PDF-Format. Seitengröße. Anzunehmende Browserbreite

Inhalt. Teil I: Der Sprachkern von JavaScript

Modul 8: Browser-Processing- Pipeline

ANWENDUNGSSOFTWARE CSS

Web-Techniken Einführung in JavaScript

CSS. Cascading Style Sheets

Funktionen in JavaScript

JavaScript. - mailto: hush.com danke Erik und Andi

Organisatorisches. Neue Übungsblätter: Nur mehr elektronisch? Abgabe Di, , 14 Uhr bis Do, , 8Uhr

CSS - Cascading Stylesheets

JavaScript. Dies ist normales HTML. Hallo Welt! Dies ist JavaScript. Wieder normales HTML.

hotelanfrage_sample <td align = "center"> <select name=dy0 size=1 class="smalltext"> <option selected value="0"><< kein Erwachsener

Organisatorisches. drei Gruppen Gruppe 1: 10:10-11:40, Gruppe 2: 11:45-13:15 Gruppe 3: 13:20-14:50

Funktionen. - sind kleine, meist ausgelagerte Programme bzw. Programmfragmente. - können Werte zurückgeben, z.b. Berechnungen

JavaScript O'REILLY. Das umfassende Referenzwerk. Deutsche Übersetzung von Ralf Kuhnert, Gisbert W. Selke & Harald Selke

E-Commerce: IT-Werkzeuge. Web-Programmierung. Kapitel 3: Webdesign mit CSS Stand: Übung WS 2015/2016. Benedikt Schumm M.Sc.

Funktionen in JavaScript

Eine Schnelleinführung in CSS

HTML Scripting. Informatik 1 für Nebenfachstudierende Grundmodul. Kai-Steffen Hielscher Folienversion: 06. Dezember 2017

Klausurteilnehmer. Wichtige Hinweise. Note: Klausur Informatik Programmierung, Seite 1 von 8 HS OWL, FB 7, Malte Wattenberg.

3. Briefing zur Übung IT-Systeme

Übung: Bootstrap - Navbar

JavaScript II. Hochschule Karlsruhe Technik & Wirtschaft Internet-Technologien T3B250 SS2014 Prof. Dipl.-Ing. Martin Schober

Objekte haben eine eigene Notation, also Schreibweise, beim Aufruf:

JavaScript und das Document Object Model

4. Briefing zur Übung IT-Systeme

O'REILLT Beijing Cambridge Famham Köln Paris Sebastopol Taipei Tokyo. JavaScript. Das umfassende Referenzwerk. David Flanagan

Inhalt HTML 2. Applets Frames Formulare CSS cascading style sheets. Lehrveranstaltung Internet in AT Dr.-Ing. A. Braune TECHNISCHE UNIVERSITÄT DRESDEN

Ereignisse Auf Benutzereingaben reagieren


Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 16/17. Kapitel 13. Listen. Listen 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 15/16. Kapitel 12. Listen. Listen 1

Die Klasse string Verfasser: Christian Bartl

Multimedia im Netz Wintersemester 2013/14. Übung 05 (Nebenfach)

Digitale Medien. Übung zur Vorlesung. Vorlesung: Heinrich Hußmann Übung: Renate Häuslschmid

Übung zur Vorlesung. Digitale Medien. Vorlesung: Heinrich Hußmann Übung: Renate Häuslschmid, Hanna Schneider

Web-basierte Anwendungssysteme XHTML- CSS

Web-Anwendungen, SS17 - Fragentypen

HTML - Die Sprache des Internets. Grundlagen und Kurzprojekt

javascript Coding-Guidelines 2. Ausgabe Februar 2015 Der Guideline beschreibt den verwendeten Coding-Stil von javascript als eigene Richtline.

4. Briefing zur Übung IT-Systeme

Inhalt. 1 Mit CSS beginnen 1. 2 Textauszeichnungen und andere Grundlagen 13

Ändern der Schriftgröße für den Monitorexport

Introduction to Technologies for Interaction Design. Stylesheets

Computergrundlagen HTML Hypertext Markup Language

Es gibt immer einen Schlüssel und einen zugehörigen Wert,

Position von CSS-Stilen. Inline(pro Tag) In Header. Extern in CSS-Datei

DI (FH) Levent Öztürk

Datenstrukturen und Algorithmen Beispiellösung zu Heimübungsblatt 7. Abbildung 1: Das Array A als Baum (vgl. Foliensatz 16, Folie 3)

PHP JavaScript Kapitel 9. Java-Script-Objekte und das Event-Modell

Literatur. Webtechnologien WS 2018/19 - Teil 4/CSS I

PHP MySQL - myphpadmin Formulardaten in eine Datenbank speichern

Programmieren im Web 2.0

W7 Projekt im Zusammenhang Gästebuch

Bei for-schleifen muss man nur immer bedenken, dass die letzte Anweisung immer erst nach der Ausführung der restlichen Anweisungen der Schleife

CS1024 Internetbasierte Systeme

HTML5 & SCC3. PC-Treff-BB VHS Aidlingen. Lothar R. Krukowski. Ein Überblick

Funktionen nur wenn dann

Embedded Webserver in Forth

PresseBox Presseticker

Klausur Informatik Programmierung, Seite 1 von 8 HS OWL, FB 7, Malte Wattenberg

Dynamisches Anzeigen von Informationen in APEX mit jquery UI Dialogs und Tabs

Scripting für Kommunikationswissenschaftler Gruppe C

Multimediale Web-Anwendungen. JavaScript. Einführung. MWA JavaScript-Einführung Dr. E. Schön Sommersemester 2015 Folie 1.

50 Fragen zu HTML und JavaScript - mit Antworten

HTML & CSS. GIMP > Bild > Bild skalieren Unter diesem Menüpunkt kannst du die Bildgröße verändern. Beachte die Bildproportionen

Selektoren in CSS. HTML/CSS 21. November 2013 E1. 1. Beispiel: Kinder und Enkel

Stand und Ausblick

Kennen, können, beherrschen lernen was gebraucht wird

5 BINÄRE ENTSCHEIDUNGS- DIAGRAMME (BDDS)

Entwicklung einer Webseite zur Verwaltung von Prüfungsterminen

FUNKTIONSBESCHREIBUNG. IFRAME EINBETTUNG VERSION: ab

Allgemeine Technologien II Wintersemester 2011 / November 2011 CSS

Richtlinien für das Design der KML Webseite. KML TP2, Informationsdienste

Vordiplom für Wirtschaftswissenschaften Allgemeine Informatik II SS Juli 2002 Bearbeitungszeit: 120 Minuten BEISPIELLÖSUNG

Informatik II, SS 2014

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 11/12 1. Kapitel 11. Listen. Listen

Klausur: Internet-Technologien

PHP, Ajax und JavaScript

Probeklausur Besprechung

3. Briefing zur Übung IT-Systeme

php Hier soll ein Überblick über das Erstellen von php Programmen gegeben werden. Inhaltsverzeichnis 1.Überblick Parameterübergabe...

Tutorial zum erstellen einer Webseite

Digitale Medien. Übung zur Vorlesung. Vorlesung: Heinrich Hußmann Übung: Renate Häuslschmid

Der CSS-Problemlöser

Grundlagen-Beispiel CSS

Dokumentation für Popup (lightbox)

Wenn ich mit der Maus auf das fehlende Bild gehe und Bild anzeigen wähle, dann wird das fehlende Bild angezeigt.

Transkript:

Webtechnologien Teil 13: JavaScript Document Object Model (DOM) 20.06.18 1

Übersicht Bäume Wiederholung aus CSS Architektur eines Browsers DOM Drei DOM-Projekte Display Hints Formularfarben 2

Binärer Baum (Beispiel) I Wurzel 1 Großeltern Die kursiv geschriebenen Familienbezeichnungen beziehen sich auf den mit X markierten Knoten. Knoten 2 Onkel Knoten 4 Eltern Blatt 3 Knoten X Blatt 5 Schwester Blatt 6 Blatt 7 Kind Kind 3

Binärer Baum (Beispiel) II Wurzel = root = Knoten, auf den kein anderer zeigt Blatt = leaf = Knoten, der auf keinen anderen zeigt Hierarchie = Baum ohne Zyklen (bzw. Rückwärtszeiger) Strenge Hierarchie = Jeder Knoten hat max. einen Elternknoten Binärer Baum = Baum mit Knoten mit max. 2 Zeigern N-ärer Baum = Baum mit Knoten mit max. n Zeigern 4

Das alte Beispiel aus CSS I <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> <title></title> <style> body p { color: black; } body > p { color: blue; } </style> </head> <body> <p>dies ist der erste Absatz. Er ist ein Kind von body.</p> <div> <p>dieser Absatz ein Kind von div</p> </div> <p>dieser Absatz ist wieder ein direktes Kind von body.</p> </body> </html> 5

Das alte Beispiel aus CSS II Der Baum netbeans Erstellt mit https://codebeautify.org/xmlviewer 6

Das alte Beispiel aus CSS III Der Baum html head body meta title style p div p text text p text text 7

Globale Architektur eines Browsers I Daten html CSS Bilder Ajax html-/css- Prozessor Video JavaScript- Prozessor Strings Operationen auf Knoten Audio Operationen auf Knoten DOM- Prozessor Interpretation von Knoten Browser Viewer 8

Globale Architektur eines Browsers II Aus der HTML-Information wird der JavaScript-Teil extrahiert. JavaScript kann durch Ausgabe von Strings (via document.write()) oder durch Setzen des innerhtml-attributes HTML an den HTML-Prozessor senden. JavaScript kann aber auch durch Operationen auf den Knoten das Document Object Model (DOM) abfragen und ändern. Jede Änderung des DOM wird unmittelbar durch den Viewer zur Ausgabe gebracht. Mit Hilfe von Ajax kann auf Daten von außerhalb zugegriffen werden. 9

Document Object Model (DOM) I Das gesamte Dokument wird in Knoten zerlegt und diese in einem Baum angeordnet. Das Document Object Modell (DOM) beschreibt die hierarchische Struktur der durch das HTML-Dokument definierten Objekte. Das DOM beschreibt damit die interne hierarchische Repräsentation des Dokuments als Baum. Zusätzlich werden alle Bibliotheksfunktionen in denselben Baum integriert. Das DOM ist die API für den Zugriff auf die Bestandteile des Dokuments. In diese API sind auch Objekte von JavaScript integriert, z.b. String. Siehe - http://www.w3.org/dom/ - http://de.selfhtml.org/dhtml/modelle/dom.htm 10

Document Object Model (DOM) II Beginnend mit der Wurzel hin zu den Blättern wird mit der Punktnotation ein Objekt bzw. Methode bzw. Attribut adressiert: (1) wurzel.element..element (2) wurzel.element..element.attribute (3) wurzel.element..element.methode(...) wobei wurzel bzw. element für den Namen oder die Art eines Knoten steht. In (1) wird ein Knoten adressiert, in (2) ein Attribut eines Knotens ausgewählt und in (3) eine Methode eines Knotens aufgerufen. Wenn es eindeutig ist, können die vorderen Teile der Punktnotation weggelassen werden, z. B. document.write() statt window.document.write(). 11

Suchen anhand von Merkmalen node= document.getelementbyid("string") Zugriff auf ein Element mit Attribut id=string. node= document.getelementsbyname("string") Zugriff auf Elemente mit Attribut name=string, wobei diese in einem Array node[] geliefert werden node= document.getelementsbytagname("string") Zugriff auf Elemente, wobei diese in einem Array node[] geliefert werden, z.b. Zugriff auf den 3. Absatz: var absatz= document.getelementsbytagname("p")[2] 12

Attribute von Knoten Die Attribute hängen vom Typ des Knotens ab, z.b.: Attribut value: Lesen und Schreiben des aktuellen Wertes Attribut checked: Boole'scher Wert, ob angekreuzt Attribut selected: Boole'scher Wert, ob ausgewählt Attribut options[]: Array mit den Optionen der Elemente checked, selected und options sind Elemente von Formularen. 13

Beispiel für DOM-Operationen I Hello.css Hello.html Hello.js function mods() function addnode() Es wird ein Beispiel für das Zusammenspiel zwischen JavaScript, CSS und HTML vorgestellt. 14

Beispiel für DOM-Operationen II - Datei Hello.html Hello.html (01)... (02) <head> (03)... (04) <link rel="stylesheet" type="text/css" href="hello.css"> (05) <script type="text/javascript" src="hello.js"></script> (06) </head> (07) <body onload="mods()"> (08) <p id="hello">hello World!<p> (09) <div id="comment"></div> (10) </body> Hello.css.normal { color: green; font-weight: normal; font-size: 14pt; }.good { color: blue; font-weight: bold; font-size: 12pt; } 15

Beispiel für DOM-Operationen III Datei Hello.js (01) function mods() { (02) var teaser= document.getelementbyid("hello"); (03) teaser.classname= "normal"; // setzen der CSS-Klasse (04) var console= document.getelementbyid("comment"); (05) addnode(console,"das ist ein dynamisch"); (06) addnode(console,"generierter Text!"); (07) (08) var kids= console.childnodes; // array von Kindern (09) for (var i= 0;i<kids.length;i++) { (10) kids[i].classname= "good"; // setzen der CSS-Klasse (11) } (12) console.style.border= "solid red 3px"; (13) console.style.width= "300px"; (14) } getelementbyid("hello") liefert ein Element mit der id="hello"..classname= "..." weist eine CSS-Klasse einem Knoten zu..style.border= und.style.width= sind Möglichkeiten CSS-Attribute direkt ohne Klassennamen zuzuweisen. 16

Beispiel für DOM-Operationen IV - Datei Hello.js (1) function addnode(elem, text) { (2) var newdiv= document.createelement("div"); (3) elem.appendchild(newdiv); // neuer Layer-Knoten (4) var newtext= document.createtextnode(text); (5) newdiv.appendchild(newtext); // Text-Knoten einfügen (6) } Es werden zwei neue Knoten erzeugt (2) und (4) und in den Baum eingehängt (3) und (5). Das ist das Ergebnis im Browser 17

DOM-Operationen Auszug value removechild() insertbefore() appendchild() replacechild(a,b) childnodes firstchild lastchild nextsibling parentnode createelement() createtextnode() Inhalt eines Knotens Löschen eines Knotens Vorne in die Liste Einfügen Hinten in der Liste Anfügen Ersetzt b durch Knoten a Liste von Kind-Knoten in einem Array Holt den ersten Knoten der Kinder Holt den letzten Knoten der Kinder Holt das nächste Kind (Geschwister) Holt den Elternknoten Neues Element außerhalb des DOM erzeugen Neues Text-Element außerhalb des DOM erzeugen 18

Beispiel Währungsumrechner I <form> <input size="8" type="text">dm <p> <input size="8" type="text">eur<p> <input type="button" value="los!" onclick="rechner1();"> </form> function Rechner1() { var dms= document.forms[0].elements[0].value; var eurs= Math.round((dms/1.95583)*100)/100; document.forms[0].elements[1].value= eurs; } Direkte Adressierung der Elemente 19

Beispiel Währungsumrechner II <form name="euro"> <input name="dm" size="8" type="text">dm <p> <input name="eur" size="8" type="text">eur<p> <input type="button" value="los!" onclick="rechner2();"> </form> function Rechner2() { var dms= document.euro.dm.value; var eurs= Math.round((dms/1.95583)*100)/100; document.euro.eur.value= eurs; } Symbolische Adressierung der Elemente Die Benennung von Elementen und die Benutzung dieser Namen ist immer besser als die direkte Adressierung. 20

Ausgabe-Routine I Es soll eine Ausgabe in JavaScript in das aktuelle Fenster möglich sein: (01) <script... src="js/display.js"></script> (02) </head> (03) <body> (04) Lorem ipsum dolor sit amet,... ipsum dolor (05)... (06) <script> (07) Display("300px","10px","500px","150px"); (08) writeln('dada','dada','dada','dada','dada','dada'); (09) writeln(10,'m'); (10) writeln(true); (11) writeln(3.14159); (12) writeln(); (13) writeln("<b> a<b </b>","<hr>"); (14) </script> (15) </body> 21

Ausgabe-Routine II - Bemerkungen In (1) werden das Objekt und Routinen dazu eingebunden. (7) definiert das Fenster in dem Format: Display(top,left,width,height) Der Display-Aufruf ist nicht nötig; es werden Default-Werte benutzt. Dieser Aufruf dient nur dazu, wenn das Ausgabefenster bei den Defaultwerten Inhalte der Seite überdeckt und deshalb an eine andere Stelle gelegt werden soll. In (8) bis (13) wird die Ausgaberoutine writeln mit verschiedenen Parameteranzahlen und Parametertypen aufgerufen. 22

Ausgabe-Routine III - Ausgabe Analyse des Seiteninhalts 23

Ausgabe-Routine IV - Analyse Generiertes Fenster Eigenschaften des Fensters 24

Ausgabe-Routine V - Source (01) function Display(left="500px",top="40px",width="500px",height="150px"){ (02) if(document.getelementbyid("displaydisplay")===null) { (03) Display.con= document.createelement("div"); (04) Display.con.setAttribute("id", "DisplayDisplay"); (05) Display.con.style.fontSize= "10pt"; (06) Display.con.style.border= "dashed red 2px"; (07) Display.con.style.position = "absolute"; (08) Display.con.style.backgroundColor= "whitesmoke"; (09) Display.con.style.overflow= "auto"; (10) document.getelementsbytagname("body")[0].appendchild(display.con); (11) } (12) Display.con.style.left= left; (13) Display.con.style.top= top; (14) Display.con.style.width= width; (15) Display.con.style.height= height; (16) } Display.con ist der Knoten des Fensters mit den Meldungen. 25

Ausgabe-Routine VI - Bemerkungen Der Konstruktor des Objekts Display wird hier definiert. In (01) werden die vier Parameter mit Defaultwerten festgelegt. In (02) wird ein Knoten mit der id="displaydisplay" gesucht; falls er nicht existiert, wird er im Then-Teil erzeugt. Dies dient dazu, dass bei mehrfachen Aufrufen nur einziges Fenster erzeugt wird. (03) erzeugt den Knoten, der in (04) mit id="displaydisplay" versehen wird. In (05) bis (09) werden die CSS-Eigenschaften des Fensters gesetzt. In (10) wird der Knoten ans Ende des Body-Elements eingefügt. Dazu werden alle Knoten vom Typ "body" in einem Array geliefert, dessen 1. Index (Wert 0) zum Einhängen mit der Routine appendchild() benutzt wird. In (12) bis (15) werden die Koordinaten der linken oberen Ecke sowie Höhe und Breite festgelegt. Diese Werte können später durch einen erneuten Aufruf von Display() geändert werden. 26

Ausgabe-Routine VII - Sourcecode (17) Display.con= null; (18) Display.TextLines= ""; // line buffer (19) Display.do= function(text="",append="<br>") { (20) Display.TextLines+= text+append; (21) Display.con.innerHTML= Display.TextLines; (22) }; (23) function writeln() { (24) var text; (25) if(display.con=== null) { (26) Display(); (27) } (28) for (var i= 0;i < arguments.length; i++) { (29) text= ""+arguments[i]; (30) Display.do(text.replace(/</g,"<") (31).replace(/>/g,">")," "); (32) } (33) Display.do(); // end of line anfügen (<br>) (34)} 27

Ausgabe-Routine VIII - Bemerkungen In (17-18) werden zwei globale Variablen deklariert initiiert. Die Schreibweise "Display." davor sorgt für die Zuordnung zum Objekt Display und erfüllt damit auch gleich die Funktion eines Namensraums, so dass keine Kollisionen mit anderen Variablen auftreten. Die interne Funktion do() in (19-22) dient der Ausgabe. Dazu wird der neue Text hinten an den globalen String TextLines mit einem <br> ergänzt angefügt. Dann wird der bisher über mehrere Aufrufe zusammengesetzte gesamte Text dem Fenster als HTML-Code in (21) zugewiesen. Die writeln()-funktion bereitet die Ausgabe vor, indem nach einer einmaligen Initialisierung in (25-27) die Parameter jeweils einzeln in Strings konvertiert (29) mit einem Blank getrennt (31) zusammengesetzt werden. Vorher werden noch alle < und > mit dem RegExp- Objekt durch HTML-Ersatzzeichen ersetzt (30-31). Am Ende (33) wird noch ein <br> angefügt. 28

Formulare I - Struktur Vorher Nachher Es soll möglich sein Meldungen aufgrund der Analyse des Formular-Inhalts an den Formularelementen zu platzieren. Diese Meldungen sollen verschwinden, wenn der/die Surfer/in das korrespondierende Element ändert, genauer: den Fokus darauf setzt. 29

Formulare II - Struktur (01) <form id="formular"> (02) <table> <tr> <td align="right"> (03) <label for="vorname">vorname:</label> (04) <input id="vorname" type="text"/> (05) </td> (06) <td align="right"> (07) <label for="nachname">nachname:</label> (08) <input id="nachname" type="text"/> (09) </td> </tr> (10) <tr><td align="right"> (11) <label for="city">stadt:</label> (12) <input id="city" type="text"/> (13) </td> (14) <td align="right"> (15) <label for="street">straße:</label> (16) <input id="street" type="text"/> (17) </td> </tr> (18) <tr><td colspan="2" align="right"> (19) <button>abschicken</button> (20) </td></tr> (21) </table></form> 30

Formulare III - Bemerkungen (01) Das Formular hat eine ID ("formular"). (04,08,12,16) Jedes Formularelement hat eine ID. In (18) werden die beiden Spalten der Tabelle zusammengefasst; der Knopf wird rechtsbündig positioniert. Es werden zwei JavaScript-Dateien eingebunden: Hint.js und ColorForm.js hier nicht dargestellt. Benutzen Sie immer für einmalige Elemente IDs und achten Sie darauf, dass diese IDs auch eindeutig sind. Die Browser akzeptieren auch die mehrmalige Benutzung derselben ID das ist aber eigentlich nicht in Ordnung. Für mehrmalige Benutzung ist name= vorgesehen. 31

Hint.js I - Konstruktor Aufrufbeispiele (a) Hint("Vorname","Mit dem Vornamen stimmt etwas nicht","red"); (b) Hint("Nachname","Der Nachname ist falsch"); Realisierung (01) function Hint(nodeID,msg= null,color= null) { (02) var node= document.getelementbyid(nodeid); (03) if(color!==null) { (04) Hint.bdColorRestore= node.style.bordercolor; (05) Hint.bdColorSet= color; (06) } (07) Hint.remove(nodeID); (08) var pos= Hint.position(node); (09) Hint.create(node,msg,pos.left+'px',pos.top+'px'); (10) } 32

Hint.js II - Bemerkungen (a) zeigt ein Beispiel mit Setzen der Rahmenfarbe auf Rot. Das Umfärben muss beim ersten Aufruf (oder jedes Mal) definiert werden. In (b) wird das Input-Element "Nachname" mit einer Meldung versehen. Mit dem 3. Parameter lässt sich der Rahmen beim Generieren der Meldung einfärben, z.b. "red". In (04) wird die aktuelle Farbe in die Objekt-lokale Variable Hint.bdColorRestore kopiert. In (05) wird die zu setzende Farbe in die Variable Hint.bdColorSet kopiert. (07) entfernt eine alte Meldung, sofern sie vorhanden ist. In (08) werden die Koordinaten sowie die Breite und Höhe des Input- Elements festgestellt und als Objekt zurückgeliefert. In (09) wird die Meldung generiert und in das DOM eingehängt. pos.left und pos.top sind die Koordinaten als Integer; diese müssen zum String in der Einheit Pixel (px) umgewandelt werden. 33

Hint.js III Funktion create() (01) Hint.create= function(node,msg,left= "100px",top= "40px") { (02) var h= document.createelement("div"); (03) h.setattribute("name", "HintHint"); (04) h.setattribute("id", node.id+"_hint"); (05) h.style.fontsize= "10pt"; h.style.border= "solid red 1px"; (06) h.style.position = "absolute"; (07) h.style.backgroundcolor= "#D0FA58"; (08) h.style.wordwrap="break-word"; (09) h.style.textalign= "left"; (10) h.innertext= msg; (11) h.style.left= left; h.style.top= top; h.style.width= "100px"; (12) h.style.height= Math.ceil(msg.length/16)*16+'px'; (13) node.parentnode.appendchild(h); // insert it into DOM (14) node.addeventlistener("focus",function(){ (15) Hint.remove(node.id); (16) }); (17) if(typeof Hint.bdColorSet!=="undefined") { (18) node.style.bordercolor= Hint.bdColorSet; (19) } (20) }; 34

Hint.js IV Bemerkungen In (02) und (03) bekommt jede Meldung einen eindeutigen Namen (id="vorname_hint") und einen gemeinsamen Namen (name="hinthint"). (08) veranlasst, dass zu lange Meldungen über mehrere Zeilen linksbündig (09) umgebrochen werden. In (10) wird der Text ohne HTML-Interpretation als Inhalt für das DIV geschrieben. Es wird damit ein Layer/div mit folgenden Attributen gebaut: <div name="hinthint" id="vorname_hint" style="font-size: 10pt; border: 1px solid red; position: absolute; background-color: rgb(208, 250, 88); overflow-wrap: break-word; text-align: left; left: 225px; top: 22px; width: 100px; height: 48px;"> Mit dem Vornamen stimmt etwas nicht </div> 35

Hint.js V Bemerkungen Zeile (11) definiert die Position sowie die Breite der Meldung; diese ist immer konstant 100px. In (12) wird die Höhe der Box für die Meldung bei einer Fontgröße von 10px geschätzt. Dies könnte bei anderen Fonts fehlerhaft sein. In (13) wird die Meldung als Schwester des Input-Elements in den DOM eingefügt. ParentNode liefert den nächsten höheren Knoten in Richtung Wurzel. In (14-16) wird eine anonyme Funktion definiert, die als globalen Wert node.id zum Zeitpunkt der Definition erhält. So etwas heißt Closure. Diese Funktion wird als Listener nach dem Observer/Listener-Muster registriert und immer dann aufgerufen, wenn der Fokus auf das Input-Element gesetzt wird (Parameter "focus"). In dieser Funktion wird die Meldung gelöscht. Diese Konstruktion macht so etwas wie: onfocus="hint.remove(node.id);" (17-18) setzt die Farbe des Rahmens auf den alten Wert zurück. 36

Hint.js VI - Effekte (a) (b) (11) Hint("Vorname","Mit dem Vornamen stimmt etwas nicht","red"); (12) Hint("Nachname","Der Nachname ist falsch"); Situation (a) direkt nach der Abarbeitung von (11) und (12), (b) nach dem Setzen des Fokus mit der Maus in das Feld Vorname. 37

Hint.js VII getdimensions() Routine zur Bestimmung der Koordinaten sowie der Größe eines Elements. (01) Hint.getDimensions= function(node= null){ (02) if(typeof node.offsettop === 'undefined'){ (03) throw "Hint.getDimensions(): object has not an offset"; (04) } (05) var desc= { height: node.offsetheight, (06) width: node.offsetwidth }; (07) var leftcnt= 0, topcnt= 0; (08) while ((node!==null)&&(node.tagname!=='body')){ (09) leftcnt+= parseint(node.offsetleft); (10) topcnt += parseint(node.offsettop); (11) node= node.offsetparent; (12) } (13) desc.left= leftcnt; desc.top= topcnt; (14) return desc; (15)}; 38

Hint.js VIII Bemerkungen Es wird ein Objekt mit den x- und y-koordinaten sowie der Breite und der Höhe als Returnwert berechnet (desc). In (02) wird geprüft, ob das Verfahren überhaupt angewendet werden kann, falls nicht, wird eine Exception (03) geworfen. In (05-06) wird die Breite und die Höhe direkt abgefragt. In der Schleife (07) bis (12) werden die Koordinaten zum absoluten Rand (body) berechnet. Die Offsets left und top sind die Abstände zum nächst umfassenden Element, d.h. nicht die absoluten Koordinaten zum Fenster. Durch das stückweise herauf-gehen (11) bis zum Body-Knoten werden die einzelnen Offsets bestimmt und addiert. Da diese Werte als Strings mit der Einheit Pixel geliefert werden, müssen sie in (09) und (10) nach Integer umgerechnet werden. Das Ergebnis sind Integerwerte für die Koordinaten, die in (13) in das Return-Objekt angehängt werden. 39

Hint.js IX Position() (01) Hint.position= function(node) { (02) var dim= Hint.getDimensions(node); (03) return { left: 5+dim.left+dim.width, (04) top: dim.top+math.floor(dim.height/2) }; (05) }; Nach der Bestimmung der Koordinaten des Input-Elements in (02) werden die Koordinaten der rechten unteren Ecke berechnet. Der x-wert wird um 5px nach rechts erhöht (03). Der y-wert wird etwa mittig vergrößert (04). Math.floor rundet nach unten ab. Beide Werte werden als Integer-Werte in einem Objekt zurückgeliefert (und von create() benutzt). 40

Hint.js X Löschen von Mitteilungen (01) Hint.remove= function(nodeid) { (02) var node= document.getelementbyid(nodeid+"_hint"); (03) if(node!==null) { (04) node.remove(); (05) } (06) if(typeof Hint.bdColorRestore!=="undefined") { (07) node= document.getelementbyid(nodeid); (08) node.style.bordercolor= Hint.bdColorRestore; (09) }}; (10) Hint.removeAll= function() { (11) var hints= document.getelementsbyname("hinthint"); (12) var len= hints.length; (13) for(var i= 0;i<len;i++) { (14) if(typeof Hint.bdColorRestore!=="undefined") { (15) var str= hints[0].id; (16) var node= document.getelementbyid(str.substring(0,str.length-5)); (17) node.style.bordercolor= Hint.bdColorRestore; (18) } (19) hints[0].remove(); //side effect to hints[] (20) }}; 41

Hint.js XI Bemerkungen remove(nodeid) löscht den Knoten (04) einer einzelnen Mitteilung am Element mit der ID=nodeID und setzt optional die Farbe des Rahmens wieder zurück (08). removeall() löscht alle Mitteilungen einer Seite, also für alle Formulare. Alle Mitteilungen haben den gemeinsamen Namen="HintHint". Die Liste dieser Knoten wird in (11) erstellt. Wenn in der Schleife (13-20) die Knoten schrittweise gelöscht werden, verkleinert sich auch gleichzeitig das Array mit den noch vorhandenen Knoten; daher wird die Anzahl in der Variablen len vor der Schleife vermerkt (12) und immer nur das erste Element des Arrays gelöscht (19). In der IF-Konstruktion (14-18) wird die Farbe des Rahmens wieder zurück gesetzt. Dazu muss die ID der Input-Elemente bestimmt werden. Dies erfolgt, indem z.b. von "Vorname_Hint" der hintere Teil abgeschnitten und als ID verwendet wird (16), also "Vorname". Dies korrespondiert zur create()-funktion. 42

Aktivieren der eigenen Prüfroutinen (01) <tr> <td align="right"> (02) <label for="vorname">vorname:</label> (03) <input id="vorname" type="text" onblur="mycall('vorname');"/> (04) </td> (05) function mycall(nodeid) { (06) var node= document.getelementbyid(nodeid); (07) writeln('mycall(',nodeid,'):',node.value); (08) } In (03) wird die Funktion mycall mit der ID des Input-Elements aufgerufen, wenn der/die Surfer/in mit der Maus das Formularfeld verlässt. In mycall() wird dann in (06) der Knoten bestimmt, um mit Hilfe regulärer Ausdrücke dessen Wert (node.value) zu prüfen. Hier wird stattdessen einfach eine Meldung ausgegeben (08). 43

Einfärben aktiver Formularelemente <form id="formular">... </form> ColorForm("formular","yellow"); Das Element mit dem Fokus wird gefärbt; die Farbe wird nach dem Verlassen des Fokus wieder auf den alten Wert zurückgesetzt. 44

ColorForm.js I - Konstruktor (01) function ColorForm(formID,focus= "yellow",blur= null) { (02) ColorForm.fcolor= focus; (03) var fobj= ColorForm.getForm(formID); (04) if(blur===null) { (05) ColorForm.bcolor= fobj.color; (06) } else { (07) ColorForm.bcolor= blur; (08) } (09) ColorForm.setForm(fobj.node); (10) } Die beiden globalen Variablen ColorForm.fcolor (Fokus) und ColorForm.bcolor (Blur) enthalten die Farben für die beiden Ereignisse. In (03) wird der Knoten für das Formular (ID= ) sowie die ursprüngliche Farbe geholt, in der Variablen fobj abgelegt und in (05) bzw. (07) gesetzt. ColorForm.getForm() wird später erklärt. In (09) wird das ganze Formular bearbeitet. ColorForm.setForm() wird später erklärt. 45

ColorForm.js II - getform() (01) ColorForm.getForm= function(formid) { (02) var form= document.getelementbyid(formid); (03) if (form===null) { (04) throw "setform(): id of form doesnt exist"; (05) } (06) var elements= form.elements; (07) return { node: form, (08) color: elements[0].style.backgroundcolor }; (09) }; Diese Funktion liefert den Formular-Knoten und die ursprüngliche Farbe in (07-08). In (06) wird eine Liste aller Elemente des Formulars generiert. Von dieser Liste wird das 1. Element genommen und dessen Hintergrundfarbe als die ursprüngliche angenommen (08). 46

ColorForm.js III - setform() (01) ColorForm.setForm= function(form) { (02) var elements= form.elements; (03) for (var i= 0;i<elements.length ;i++) { (04) if (elements[i].type==="text") { (05) ColorForm.attach(elements[i]); (06) } (07) } (08) }; Diese Funktion bestimmt anhand des Formular-Knotens die Liste aller Formularelemente und ruft in (05) für jedes dieser Elemente die attach()-funktion auf, vorausgesetzt es handelt sich um eine Input-Text-Element (04). ColorForm.attach() wird später erklärt. 47

ColorForm.js IV - attach() (01) ColorForm.attach= function(node) { (02) if(typeof ColorForm.bcolor!=="undefined") { (03) node.addeventlistener("focus",function(){ (04) node.style.backgroundcolor= ColorForm.fcolor; (05) }); (06) node.addeventlistener("blur",function(){ (07) node.style.backgroundcolor= ColorForm.bcolor; (08) }); (09) } (10) }; Die attach()-funktion ordnet nun den Knoten node das Setzen der Farbe ColorForm.fcolor beim Fokus- und das Setzen der Farbe ColorForm.bcolor beim Blur-Ereignis zu. Das erfolgt durch zwei anonyme Funktionen (Closures), die jeweils bei Focus (03) bzw. bei Blur (07) aufgerufen werden. Beide Funktionen werden beim Formularelement node registriert. 48

Nach dieser Anstrengung etwas Entspannung... 49