3. Clientseitige Verarbeitung und Javascript Inhalt: Javascript Einbindung von Javascript-Funktionen in Webseiten DOM-Referenzierung Realisierung dynamischer Effekte über das DOM Exkurs: Objektorientiert Programmieren mit Javascript 1 Javascript Javascript wurde 1995 im Netscape-Browser eingeführt und wird inzwischen von den meisten Browsern unterstützt. Allgemeines: Skripte werden mit der HTML/XHTML-Seite übertragen und deren Ausführung durch verschiedene Ereignisse angestoßen Diese Skripting-Erweiterung bleibt im Rahmen einer 2-Tier Architektur. Javascript erlaubt dynamische Effekte bei Darstellung der Webseiten. Java bzw. C- ähnliche Sprache prozedural und objektorientiert 2
Javascript Javascript wurde 1995 im Netscape-Browser eingeführt und wird inzwischen von den meisten Browsern unterstützt. Allgemeines: Skripte werden mit der HTML/XHTML-Seite übertragen und deren Ausführung durch verschiedene Ereignisse angestoßen Diese Skripting-Erweiterung bleibt im Rahmen einer 2-Tier Architektur. Javascript erlaubt dynamische Effekte bei Darstellung der Webseiten. Java bzw. C- ähnliche Sprache prozedural und objektorientiert 3 Javascript-Minimalbeispiel <html> <head> <title>eine Seite mit Javascript</title> <script type= text/javascript > alert( Hier spricht das Javascript! ); </head> <body> </body> </html> 4
Javascript - Variablen <html> <head> <title>eine Seite mit Javascript</title> function fun() { var x; x=42; alert("die magische Zahl ist "+x); </head> <body > <form name="formular" action=""> <input type="button" value="action!" onclick="fun()"/> </form> </body> </html> Variablen sind mittels var zu deklarieren. keine Typ-Angabe nötig 5 Javascript - Variablen <html> <head> <title>eine Seite mit Javascript</title> function fun() { var x; x=42; var Nachricht = "Die magische Zahl"; ; alert( Nachricht+" ist "+x); </head> <body > <form name="formular" action=""> <input type="button" value="action!" onclick="fun()"/> </form> </body> </html> Zeichenketten können per + zusammengebaut werden 6
Javascript - Alternative function fun() { var x; x=eingabe.text; var Nachricht; if (x==42) { Nachricht = "Die magische Zahl"; else { Nachricht = Die gewoehnliche Zahl ; alert( Nachricht+" ist "+x); Alternativen mittels if (bedingung) else Bedingungen mit Relationen<,>,==,<=,>= Logische Verknüpfungen: && (UND), (ODER),! (NEGATION) 7 Javascript Zyklus (1) function fun() { var x; x=document.eingabe.value; var Nachricht; var i = 0; while (i <=x) { alert( Der + i + te Durchgang! ); i=i+1; Zyklen mittels while( ) { oder do { while( ); möglich. 8
Javascript Zyklus (2) function fun() { var x; x=document.eingabe.value; var Nachricht; var i = 0; for(i=0; i<=x; i++) { alert( Der + i + te Durchgang! ); For-Schleifen vorzugsweise dann, wenn vorab bekannt ist, wieviele Durchläufe erfolgen sollen. 9 Javascript Zyklus (3) Für while-, do-while- und for-schleifen kann per break vorzeitig aus der Wiederholung ausgetreten werden continue der aktuelle Schleifendurchlauf beendet werden und mit dem nächsten Durchlauf fortgesetzt werden. Beispiel: <script type= text/javascript > Es werden die var i=0; Listenpunkte von 1 bis 19 while(i<10000) erzeugt, mit Ausnahme { if (i==20) break; von 7 und 13 i++; if (i==7 i==13) continue; document.write( <li>listenpunkt +i+ </li><br/> ); 10
Javascript Funktionen Ohne Parameter und Rückgabewert: function fun() { // hier der Code Mit Parametern und Rückgabewert: function calculate(a, b) { var c = a * (1 + (b / 100)); return c; 11 Javascript Felder (1) Vereinbarung der Felder: var werte= new Array(100); var 3dpos = new Array(2);... for (i=0;i<=100;i++) { werte[i]=i*2; 3dpos[0]=x; 3dpos[1]=y; 3dpos[2]=z; Die Feldelemente werden beginnend mit 0 nummeriert. Wenn n Elemente vereinbart werden, dann besitzt das Feld n+1 Elemente (von Index 0 bis n). Das ist ein Unterschied gegenüber C. len = werte.length(); // gibt Anzahl Elemente zurueck, hier speziell 101 12
Mehrdimensionale Felder Javascript Felder (2) var 3dpositions = new Arrray(5); for (i=0;i<3dpositions.length;i++) 3dpositions[i] = new Array(2); for (i=0;i<=5;i++) { 3dpos[i][0]=x[i]; 3dpos[i][1]=y[i]; 3dpos[i][2]=z[i]; 13 Javascript Felder (3) Verschiedene Varianten zum Anlegen von Feldern: über die Anzahl der Elemente var 3dpos = new Array(2); über die Initialisierung der Elemente Objektname = new Array(Element0, Element1,..., element_n); MeineKinder = new Array( Max", Moritz", Hensel", Gretel"); Ohne Länge MeineVorlesungen = new Array(); //Elemente entstehen durch ihre Referenzierung meinevorlesungen[0]="internettechnologien"; meinevorlesungen[1]="parallele Programmierung"; meinevorlesungen[2]="informatik für Chemiker"; Peter Sobe Internettechnologien 14
Javascript Felder (4) Assoziative Felder Elemente können über ihren Inhalt referenziert werden Beispiel aus selfhtml.org: var Mitarbeiter = new Array(); Mitarbeiter[0] = new Object(); Mitarbeiter[0]["Name"] = "Müller"; Mitarbeiter[0]["Vorname"] = Fred"; Mitarbeiter[0]["Wohnort"] = "Dresden"; Mitarbeiter[1] = new Object(); Mitarbeiter[1]["Name"] = "Schulze"; Mitarbeiter[1]["Vorname"] = Maria"; Mitarbeiter[1]["Wohnort"] = "Berlin"; 15 Javascript Felder (5) Assoziative Felder (Fortsetzung) Beispiel aus selfhtml.org: for (var i = 0; i < Mitarbeiter.length; i++) { document.write("<dl><dt>mitarbeiter " + (i + 1) + "<\/dt>"); for (var Eigenschaft in Mitarbeiter[i]) document.write("<dd>" + Eigenschaft + ": " + Mitarbeiter[i][Eigenschaft] + "<\/dd>"); document.write("<\/dl>"); 16
Javascript Einbindung der Funktionen Im Javascript-Element werden eine oder mehrere Funktionen definiert. <script type= text/javascript > var z=0; // global variable function1() { alert( z= +z); function2() { z=z+1; Es können auch mehrere Javascript-Elemente in einem Dokument eingebunden werden. Das wird gern benutzt, wenn Skripte aus externen Quelldateien eingebunden werden. <script type="text/javascript" src="../jsclasses/myjsfunctions.js" > function test(){ 17 Javascript Aufruf der Funktionen (1) Als Beispiel wurden drei Funktionen definiert, die nun auf unterschiedliche Art aufgerufen werden. Bei Laden der Webseite: <body onload= test() > </body> Bei Button-Klick: <input type= button value= OK onclick= function1() > Bei Formular-Aktionen: <form id= Formular1 action= method= post onsubmit= function1() onreset= function2() > <input id= werteingabe type= text size= 5 > <input type= submit > value= Berechnen /> <input type= reset > value= Abbruch /> </form> 18
Javascript Aufruf der Funktionen (2) Zeitgesteuerter Aufruf (Zeitwert in Millisekunden): <body onload= settimeout(test(),1000) > </body> Aufruf der Funktionen untereinander: function1() { // do something function2(); Generelles Konzept: Ein Eventhandler reagiert auf Ereignisse, die von HTML-Elementen mit entsprechenden Attributen (onclick, onload usw.) ausgelöst werden. In den Ereignis-Attributen kann direkt Javascript-Code notiert werden, oder der Aufruf von Funktionen innerhalb eines Javascript-Elements ausgelöst werden. Attribute (Auswahl): onclick für button, onchange für text, textarea, onmouseover, onload/onunload für HTML-Seiten(body) 19 Javascript Aufruf der Funktionen (3) Inline-Skripte: Diese Skripte stehen innerhalb des Body und werden mit den Laden des HTML-Dokuments ausgeführt. Sie erzeugen oftmals Elemente der Webseite (auf automatisierte Art und Weise). * Listenpunkt 1 * Listenpunkt 2 * Listenpunkt 3 * Listenpunkt 4 * Listenpunkt 5 * Listenpunkt 6 * Listenpunkt 7 * Listenpunkt 8 * Listenpunkt 9 <html><head><title>test</title></head> <body> var i; document.write("<ul>"); for (i = 1; i!= 10; i++) document.write("<li> Listenpunkt " + i + "</li>"); document.write("</ul>"); 20
Javascript Aufruf der Funktionen (4) Inline-Skripte (Fortsetzung): Wenn document.write( "); nicht erlaubt ist, können bereits bestehende Elemente gefüllt oder erweitert werden. <div id="platzhalter1"></div> <div id="platzhalter2"></div> <div id="platzhalter3"></div> <div id="platzhalter4"></div> <div id="platzhalter5"></div> var i; for (i=1;i!=6;i++) { document.getelementbyid("platzhalter"+i).innerhtml="<p><font color='blue' size='4'>listenpunkt"+i+"</font></p>"; alert("platzhalter"+i); 21 Javascript in XHTML Das Javascript ist ein normales Element im DOM Vergleichsoperatoren <,>,<=,=> innerhalb des Skriptes werden als Tag-Kennzeichen gewertet (Problem!). Mit Kommentar: <script type= text/javascript > /*<![CDATA[*/ function calculate(a) { var c = 1; for (i=1;i<=a; i++) c= c*i; return c; /*]]>*/ Erklärung: Zeichen <,>,&, sind innerhalb Elementen nicht erlaubt. XML-Parser übergeht Bereiche, die durch <![CDATA[. ]]> eingefasst sind. 22
Javascript DOM-Referenzierung (1) Knoten Attribute Vater/Kind-Knoten Siblings (Geschwisterknoten) Vater Kinder Geschwister 23 Javascript DOM-Referenzierung (2) Werte über DOM-Referenz var z = document.formular1.eingabe.value; Funktioniert nur eingeschränkt! var e = document.getelementbyid( element-id ); Über e können Werte ausgelesen und gesetzt werden. eingabe = e.value; e.value= Standardwert ; 24
Javascript DOM-Referenzierung (3) Lesen und Setzten von Attributen: var e = document.getelementbyid( element-id ); Über e können Attribute ausgelesen und gesetzt werden. a = e.getattribute( attr-name ); e.setattribute( attr-name, attr-value ); Verkürzte Schreibweise: document.getelementbyid( element-id ).setattribute( attr-name, attr-value ); 25 Javascript DOM-Referenzierung (4) Javascript-Funktionen zum Zugriff auf Dokumenteigenschaften Zugriff aus Kind-Knoten: firstchild, lastchild Beispiel aus SelfHTML.org <body> <ul><li>erster Punkt</li> <li>zweiter Punkt</li> </ul> var ErsterPunkt = document.getelementsbytagname("ul")[0].firstchild; document.write(ersterpunkt.firstchild.data); </body> 26
Javascript DOM-Referenzierung (5) Zugriff auf Geschwister-Knoten: nextsibling (auch previoussibling) Beispiel aus SelfHTML.org <body> <ul><li>erster Punkt</li> <li>zweiter Punkt</li> </ul> document.write("das ul-element hat folgende Knoten unter sich:<br>"); var Knoten = document.getelementsbytagname("ul")[0].firstchild; while (Knoten!= null) { document.write("einen Knoten mit dem Namen <b>" + Knoten.nodeName + "<\/b><br>"); Knoten = Knoten.nextSibling; </body> 27 Javascript DOM-Referenzierung (6) Test, ob Kind-Knoten vorhanden: haschildnodes() gibt true oder false zurück, je nach dem ob das referenzierte Element Kindknoten besitzt oder nicht Element: nodename Knoten = document.getelementbyid("dasscript"); var Knoten = document.body.firstchild; document.write("dieses Script-Element hat folgende Knotennamen: <b>" + Knoten.nodeName + "</b>"); 28
Javascript DOM-Referenzierung (7) nodetype <html><head><title>test</title> </head><body> <p align="center">ein kleiner Text</p> var Element = document.getelementsbytagname("p")[0]; var Ausrichtung = Element.getAttributeNode("align"); alert(ausrichtung.nodetype); </body> </html> Knotentypen können Elementknoten (Kodierung 1), Attributknoten (2), Textknoten (3) und weitere sein 29 nodevalue Javascript DOM-Referenzierung (8) function TextAendern () { document.getelementbyid("dertext").firstchild.nodevalue = document.formular.neuertext.value; parentnode </head><body> <ul> <li>ein Punkt</li><li>ein zweiter</li></ul> alert(document.getelementsbytagname("li")[0].parentnode.parentnode.tagna me); </body> 30
Javascript Dynamische Effekte per DOM (1) InsertBefore <html><head><title>test</title></head> <body> <p id="dertext">text <i id="derkursivetext">und mit kursivem Text</i></p> var neub = document.createelement("b"); var neubtext = document.createtextnode("mit fettem Text "); neub.appendchild(neubtext); document.getelementbyid("dertext").insertbefore(neub, document.getelementbyid("derkursivetext")); </body></html> 31 Javascript Dynamische Effekte per DOM (2) Einfügen neuer Knoten per appendchild() <html><head><title>test</title></head> <body> <ol id="liste"> <li>element</li> </ol> document.getelementbyid("liste").removechild(document.getelementbyid("liste").firs tchild); for (var i = 0; i < 10; i++) { var newli = document.createelement("li"); var linr = i + 1; var newlitext = document.createtextnode("das ist Listeneintrag Nummer " + linr); document.getelementbyid("liste").appendchild(newli); document.getelementsbytagname("li")[i].appendchild(newlitext); </body></html> 32
Javascript Dynamische Effekte per DOM (3) zum Entfernen von DOM-Knoten: RemoveChild() innerhtml <html><head><title>test</title> var Neu = "neuer <b>fetter<\/b> Text"; function Aendern () { document.all.meinabsatz.innerhtml = Neu; </head><body> <p id="meinabsatz">text</p> <a href="javascript:aendern()">anderer Text</a> </body></html> 33 Javascript Objektorientiert Programmieren (1) Javascript kennt keine Klassen (im Gegensatz zu Java und C++); dennoch ist objektorientiertes Programmieren möglich Einige Aspekte: Variablen und Funktionen erzeugen intern Objekte z.b. erzeugen Funktionen s.g. Funktionsobjekte Javascript-Objekte sind assoziative Arrays mit Attributen und Methoden als Array-Elemente Man kann einem Javascript-Objekt zur Laufzeit neue Methoden zuweisen Vererbung über prototypische Objekte 34
Javascript Objektorientiert Programmieren (2) Beispiel einer Klasse mit zwei Instanzen function Klasse() { this.funktion1 = eingabe; this.funktion2 = ausgabe; function eingabe() { function ausgabe() { obj1 = new Klasse(); obj2 = new Klasse(); obj1.fuktion1(); obj2.funktion1(); obj1.funktion2(); Eine Klasse entsteht über ein Funktionsobjekt, dem man über this weitere Funktionen zuweist. 35 Javascript Objektorientiert Programmieren (3) Vererbung: function Basisklasse() { this.attribute = wert ; this.basisfunktion = b; function b() { function AbgeleiteteKlasse() { AbgeleiteteKlasse.prototyp = new Basisklasse(); obj1 = new AbgeleiteteKlasse(); obj1.basisfunktion(); Vererbung kann über das Attribut prototyp erzeugt werden. 36
Überleitung zu 3-Tier-Architekturen Bislang betrachtet: 2-Tier Architekturen 3-Tier Architekturen Webbrowser Javascript Webbrowser Javascript Javascript Javascript HTML, XML, +eingebettete Formate Webserver Webserver server-seitiges Scripting PHP 37