SlideShare uma empresa Scribd logo
1 de 98
Prototype
Inhalte Prototype
Ajax
Responders, Response, Request, (Periodical)Updater
DOM
JSON, $, $F, Abstract, Element, Form, document
Spracherweiterungen
Weitere $‘s, Array, Class, Date, Function, Object, String,
Template, Enumerable, RegExp, Prototype/Try
Prototype: Ajax.Responders
Funktion
Globale Events/Callbacks für alle Ajax Requests
Registration
Ajax.Responders.register/unregister
Callbacks
onCreate, onComplete, onException
Prototype: Ajax.Responders
Herkömmlicher Ajax Responder
Ajax.Responders.register({
onCreate: function(request,XmlHttpRequest,Json) {
alert('new request registered');
Ajax.activeRequestCount++;
},
onComplete: function(request,XmlHttpRequest,Json) {
alert('request has ended');
Ajax.activeRequestCount--;
}
});
Prototype: Ajax.Request
Funktion
Gewöhnlicher Ajax Request
Wichtige Optionen
asynchronous = true: (A)synchrone Anfrage
contentType: Ändern wenn man z.B. XML senden will
encoding = UTF8: Falls es mal Probleme mit Kodierung gibt
parameters: Parameter im URL oder JSON Format
Wichtige Callbacks
onFailure: Wird bei HTTP Errors geworfen 40x – 50x
onSuccess: Kommt zum Zug bei 20x Statuscodes
Prototype: Ajax.Request
JSON Antwortobjekt
var data = {};
data.getres = 1001;
data.language = SV_LANG_DE;
data.isIE = true;
new Ajax.Request('/pfad/zum/script/?id=685', {
parameters : data,
method : 'post',
onSuccess: function(response) {
var json = response.responseText.evalJSON();
alert('Antwort: ' + json.message);
}
});
Prototype: Ajax.Request
Synchroner Request
var data = {};
data.getres = 1001;
data.language = SV_LANG_DE;
data.isIE = true;
var myRequest = new Ajax.Request('/service/class/getres/', {
parameters : data,
method : 'post',
asynchronous : false
});
alert(myRequest.transport.responseText);
Prototype: Ajax.Response
Funktion
Antwortobjekt eines Ajax.Request
Wichtige Properties
responseText: Text der Ajax Antwort
responseXML: XMLDOM Objekt, wenn application/xml Header
responseJSON: JS Objekt, wenn application/json Header
transport: Zugriff auf das Native XmlHttpRequest Objekt
Prototype: Ajax.Updater
Funktion
Updatet einen Container, erbt von Ajax.Request
Und wozu ist das gut?
- Vereinfachung eines oft verwendeten Use-Case
- Verwendet das verhalten von Element.update()
Zusätzliche Properties
evalScripts = false: Führt Code in <script> Tags aus
insertion: Mögliche Werte: top, bottom, before, after
-> Mehr dazu bei den Element Methoden
Prototype: Ajax.Updater
Codebeispiel
<script type="text/javascript">
function UpdateChat() {
new Ajax.Updater(
{ success: 'chatWindow' },
'/getmessage/?chat=45764',
{ insertion: 'top‚ }
);
setTimeout('UpdateChat()',1000);
}
UpdateChat();
</script>
<div id="chatWindow"></div>
Prototype: Ajax.PeriodicalUpdater
Funktion
Wie Updater, führt sich aber periodisch selbst wieder aus
Wichtige Optionen
frequency = 2: Warten zwischen Abfragen
decay = 1: Erhöht die Rate von frequency, wobei der übergebene Wert
ein Multiplikator ist. 1 Hat daher keine Wirkung, 2 z.B. verdoppelt den
Wert von frequency. Wenn Resultat !=, wird frequency zurückgesetzt.
Nutzen
- Sehr wenig Code nötig für automatische Updater
- Spart Ressourcen durch den decay Parameter
Prototype: Ajax.PeriodicalUpdater
Codebeispiel
<script type="text/javascript">
new Ajax.PeriodicalUpdater(
{ success: 'chatWindow'‚ failure : 'errorMsg' },
'/getmessage/?chat=34756',
{ insertion: 'top', frequency: 2 }
);
</script>
<div id="chatWindow"></div>
<div id="errorMsg"></div>
Kurze Einführung: JSON
Wer ist Jason?
Die Javascript Object Notation
Wozu wird es verwendet?
- Objektorientiertes Javascript
- Interner Datenaustausch (z.B. Funktionsparameter)
- Externer Datenaustausch (z.B. Ajax)
Syntax
Properties, Arrays, Objektarrays, Funktionen…
… mit relativ wenig Zeichen (Leichtgewichtig)
Kurze Einführung: JSON
Einfache Daten und Arrays
var object = {
message : 'this is json',
really : true,
howmany : 1337,
inner : {
value : 'inneres objekt',
great : false
},
array : [ 1,2,3,4,5,6,7,8 ],
strings : [ 'hello', 'world' ]
};
Kurze Einführung: JSON
Objektarrays (Einfaches verschachteln)
var object = {
objectarray : [
{ message : 'this is json', really : true },
{ message : 'this is xml', really : false },
{ message : 'this is asp', really : false }
],
additional : 'hello world'
};
Kurze Einführung: JSON
Funktionen (Dazu mehr unter „Klassen“)
var Calculator = {
Add : function(param1,param2) {
return(param1 + param2);
},
Subtract: function(param1,param2) {
return(param1 – param2);
},
};
Prototype: $... Die Funktion
Funktion
Alias für document.getElementById und mehr
Wie mehr?
$(‘eleID‘) gibt ein Element zurück
$(‘eleID‘,‘inputID‘,‘textID‘) gibt ein Array zurück
DOM der Elemente wird erweitert (Dazu gleich mehr)
Nutzen
Effizienter / besser lesbarer Code
Prototype: $... Die Funktion
Typischer Code einer Validierungsroutine
// Validierbares Element holen
var ele = document.getElementById('eleID');
// Array von Werten für For basteln
var some = [];
some[0] = document.getElementById('eleID');
some[1] = document.getElementById('inputID');
some[2] = document.getElementById('textID');
// Error Message Divs ausblenden
document.getElementById('errorMessage').style.display = 'none';
document.getElementById('errorDiv').style.display = 'none';
Prototype: $... Die Funktion
Typischer Code gleicher Code mit Prototype
// Validierbares Element holen
var ele = $('eleID');
// Array von Werten für For-Schlaufe
var some = $('eleID','inputID','textID');
// Mit „hide“ Funktion auf allen Elementen, Divs ausblenden
$('errorMessage','errorDiv').invoke('hide');
Anmerkung: Die hide() und show() Methode ist nur eine der
zahlreichen DOM Erweiterungen die jedes Element bekommt
Prototype: Geht‘s noch schneller?
Eine Nanosekunde effizienter
Ja, mit der $F() Methode
Formularwert holen
Erwartet eine ID als Wert, und gibt den Wert des dahinter
liegenden Formularfeldes mit der getValue() Methode zurück.
$(‘example‘).getValue()
Gleich wie .value Property ausser bei Multiselect,
da kommt immer ein Array zurück
Prototype: Geht‘s noch schneller?
Schnell ein Formular speichern
var Assistant = Class.create();
Assistant.prototype = {
Save : function() {
new Ajax.Request('/admin/content/?id=324',
method : 'post',
parameters : {
'Name' : $F('Name'),
'Firstname' : $F('Firstname'),
'Email' : $F('Email')
}
);
}
};
Prototype: Klassen
Objektbasiert?
Orientiert, wir können Abstrakt.
Wie kann man vorgehen
- Klasse leer erstellen und Body erweitern
- Klasse direkt vollständig ausprogrammieren
Eigenheiten
Klassendefinitionen sind zur Laufzeit erweiterbar (Für alle Instanzen)
Statische Properties kennt Javascript nicht
Public, Private, Protected? Umsetzbar, aber kein Bestandteil
Prototype: Klassen
Erstellen und erweitern…
var Assistant = Class.create();
Assistant.prototype = {
// Konstruktor
initialize : function() {
},
// Speicherfunktion
Save : function() {
alert('data saved');
}
};
Prototype: Klassen
…oder direkt ausprogrammieren
var Assistant = Class.create({
// Konstruktor
initialize : function(id) {
// Hier sind meist window.onload/dom:loaded Events
},
// Speicherfunktion
Save : function() {
alert('data saved');
}
});
Prototype: Klassen
Erben des einer Klasse
var BetterAssistant = Class.create(Assistant,{
// Konstruktor
initialize : function($super,id) {
// Parent Methode aufrufen, geht bei allen überschriebenen
$super(id);
},
// Speicherfunktion überschreiben
Save : function($super) {
this.Validate(); // Erst validieren
$super();
}
});
Prototype: Klassen
Methoden überschreiben (Clean way)
BetterAssistant.addMethods({
// Speichern geht noch besser
Save : function($super) {
// Validieren und speichern
$super();
// Meldung an User geben
this.Notify();
},
// Meldung an User
Notify : function() {
$('message').update('Daten gespeichert!');
$('message').show();
}
});
Prototype: Element Erweiterungen
Wie bekomme ich die Erweiterungen
Mit Element.method() oder $(‘someElement‘).method()
Einige Beispiele
- Element.update(): Ein Block Element verändern
- Element.setStyle()/getStyle(): CSS, Browserkompatibel
- Element.show()/hide()/toggle(): Anstatt direkt CSS zu modifizieren
- Element.absolutize()/relativize(): Element Positionstyp ändern
- Element.removeClassName()/addClassName(): Sprechend
- Und 76 weitere Methoden
Welche wir hier finden
Gibt es hier: http://api.prototypejs.org/dom/element/
Prototype: Element Erweiterungen
Element.update() - Beispiel
var html = '<p>Gleich passiert was<p>' +
'<script type="text/javascript">' +
' alert("sehen sie?");' +
'</script>';
$('message').update(html);
Prototype: Element Erweiterungen
Anwendung der toString() Methode mit Element.Update()
var Fruit = Class.create({
initialize : function(name) {
this.Name = name;
}
toString: function() {
return('Hey ' + this.Name + '! I'm an orange.');
}
});
var apple = new Fruit('apple');
$('fruits').update(apple);
$('fruits').innerHTML;
Prototype: Element Erweiterungen
Klassen hinzufügen oder entfernen
<div id="msg" class="float left invisible">&nbsp;</div>
<script type="text/javascript">
$('msg').addClassName('visible','error');
$('msg').removeClassName('invisible');
// -> float left visible error
// -> toggleClassName(cssClass)
</script>
Prototype: Element Erweiterungen
XML Arbeit vereinfachen
<ul id="apples">
<li>Mutsu</li>
</ul>
<script type="text/javascript">
$('apples').firstChild.innerHTML;
// -> undefined
$('apples').cleanWhitespace();
$('apples').firstChild.innerHTML;
// -> 'Mutsu'
</script>
Prototype: Element Erweiterungen
Elementinhalt Erweitern oder umranden
// Paragraph in ein Element einbauen
$('element').insert('<p>HTML to append</p>');
// Fügt über den Paragraphen ein Bild ein
$('element').insert({
top: Element('img', {src: 'logo.png'})
});
// Fügt vor und nach dem Element ein HR ein
$('element').insert({
before: '<hr>',
after: '<hr>'
});
Prototype: Element Erweiterungen
Element bzw. Object.inspect()
$('element').inspect();
// -> <div id="element" class="hello world">
Object.inspect();
// -> 'undefined'
Object.inspect(null);
// -> 'null'
Object.inspect(false);
// -> 'false'
Object.inspect([1, 2, 3]);
// -> '[1, 2, 3]'
Object.inspect('hello');
// -> "'hello'"
Prototype: Element.Layout
Wozu
Verschiedene Grössen/Abstände eines Elements lesen
Vorteile
- Geht auch, wenn alles in CSS definiert ist
- Umgeht die Tendenz, dass Browser inkorrekte Werte liefern
- Umgeht den Quirksmodus, welcher meist gar nichts liefert
- Umgeht die Schwierigkeit mit unsichtbaren Elementen
Vorsicht
Da Resourcenintensiv sind die Werte gecached!
Prototype: Element.Layout
Instanz des Layout Objekts holen
// Mit der Element Methode verwenden
layout = new Element.Layout(element);
// Als Instanzmethode eines Elements
layout = $('element').getLayout();
// Wert lesen, CSS Version ausgeben
var pl = layout.get('padding-left');
var css = layout.toCSS();
Prototype: Element.Layout
Weitere Properties
height, width
top, left, right, bottom
border-left, border-right,border-top, border-bottom
padding-left, padding-right, padding-top, padding-bottom
margin-top, margin-bottom, margin-left, margin-right
padding-box-width padding-box-height
border-box-width border-box-height
margin-box-width margin-box-height
Prototype: Event Objekt
Events: Ein geordnetes Chaos
Error 10050, too many nerves wasted
Vorteile
- Einfache Eventregistration
- Einheitliche KEY_ Konstanten
- Einheitliches Event-Daten Objekt
- Diverse Helper Methoden
Prototype: Event Objekt
KEY_ Konstanten
KEY_BACKSPACE, KEY_TAB,
KEY_RETURN, KEY_ESC,
KEY_LEFT, KEY_UP,
KEY_RIGHT, KEY_DOWN,
KEY_DELETE, KEY_HOME,
KEY_END, KEY_PAGEUP,
KEY_PAGEDOWN, KEY_INSERT
Prototype: Event Objekt
Standard Event registrieren
function SomeFunction(event) {
// Event ist immer "event", auch im IE!
// Dieses Event Objekt ist ebenfalls erweitert
}
Event.observe(window, 'load', SomeFunction);
$(window).observe('load', SomeFunction);
$('element').observe('click', SomeOtherFunction);
Prototype: Event Objekt
Events löschen
// Genau einen Event löschen, Handler muss übergeben werden
Element.stopObserving(element,'click',SomeFunction);
$('element').stopObserving('click',SomeFunction);
// Alle Events eines Typs löschen (Keinen Handler übergeben)
Element.stopObserving(element,'blur');
$('element').stopObserving('blur');
// Oder komplett alle Event entfernen
Element.stopObserving(element);
$('element').stopObserving();
Prototype: Event Objekt
Intelligente Events (Mit Daten)
function SomeFunction(event,param) {
if (event.keyCode == KEY_RETURN) {
alert('daten sind: ' + param);
}
}
$(window).observe('keydown',function(event) {
SomeFunction(event,$('content').getValue());
});
Prototype: Event Objekt
Do it the OOP way
var AssistantClass = Class.create({
initialize : function() {
this.Input = $('myInput');
this.WeWillUseThatLater = 'Hello World';
this.Input.observe('blur',this.Validate.bind(this));
},
Validate : function(event) {
// Das Event wird im Objekt Kontext ausgeführt
alert(this.WeWillUseThatLater);
}
});
Prototype: Event Extensions
Erweiterungen am Event Objekt
Alle registrierten Events liefern ein modifiziertes ‚event‘ zurück
Beispiele
- event.element(): Das Element auf dem der Event ausgeführt wurde
- event.findElement(): Findet Objekte innerhalb des Event Elements
- event.pointerX/Y(): Für Maus Events, immer absoluter Pixelwert!
- event.is[Left|Right|Middle]Click(): Wie genau wurde geklickt?
Prototype: CSS Selektoren
Exkursion zu $$
Damit holen wir alles was mit CSS zu holen ist
Syntax Beispiele
$$(‘div.myclass‘): Alle Divs mit der Klasse myclass
$$(‘.myclass‘): Alle Elemente mit der Klasse myclass
$$(‘.myclass .error‘): Alle Elemente mit myclass und error
$$(‘#mydiv‘): Element mit der ID mydiv
$$(‘#mydiv input[type=checkbox]‘): Alle Checkboxen in #mydiv
$$(‘:checked‘): Alle ausgewählten Elemente. Weitere, :disabled :enabled
$$(‘#mytable tr:nth-child(even)‘): Alle geraden Zeilen von #mytable
…Und alles weitere was bis und mit CSS3 möglich ist!
Prototype: CSS Selektoren
Alle Checkboxen markieren
$$('#mycheckerdiv input[type=checkbox]').each(function(f) {
f.checked = true;
});
Schöne Tabelle bauen
$$(‘#mytable tr:nth-child(even)‘).each(function(tr) {
tr.className = 'AdminTabRowDark';
});
$$(‘#mytable tr:nth-child(odd)‘).each(function(tr) {
tr.className = 'AdminTabRowLight';
});
Prototype: Event.Handler
Zurück bei den Events
Diese arbeiten auf Wunsch auch mit Selektoren
Wozu ein weiterer Handler
- Der Event.Handler delegiert an Unterelemente
- Delegation des Callback erfolgt über CSS Selektoren
Prototype: Event.Handler
Einen Event Handler definieren
function SaveForm(event) {
// Formular per Prototype Ajax Post speichern
event.element.request();
}
// Speichern aller "saveable" Forms, beim verlassen der Seite
observer = new Event.Handler(
window, // Auf das Window hören
'unload', // Wenn es verlassen wird
'form.saveable', // Alle Forms mit "saveable" Klasse
SaveForm // SaveForm Methode ausführen
);
observer.start();
Prototype: Der Form Namespace
Auch die Forms sind erweitert
…Sofern diese mit der $-Funktion geladen werden
Einige Methoden im Überblick
- $(‘frm‘).disable(): Deaktiviert alle Formularelemente
- $(‘frm‘).enable(): Aktiviert alle Formularelemente
- $(‘frm‘).getElements(): Array aller Formularelemente
- $(‘frm‘).getInputs(type): Gibt z.B. alle Checkboxen eines Forms zurück
- $(‘frm‘).request(): Formular per Ajax Posten/Requesten
- $(‘frm‘).serialize(true): Formular Daten als JSON oder Query holen
Prototype: Der Form Namespace
Und sonst?
…nur einige Convenience Methoden
Form.Observer
- Trackt Änderungen in einem Formular
- Kann für generische Validation verwendet werden
Form.Element.Observer
- Gleich wie Form.Observer, auf ein einzelnes Element
- Explizite automatische Validation eines Feldes
Prototype: Der Form Namespace
Beispiele von Form(.Element).Observer
// Formular alle 500ms prüfen
new Form.Observer(myFrm, 0.5, GenericValidation);
// Formularelement alle 300ms prüfen
new Form.Element.Observer(myEle, 0.3, ExplicitValidation);
Prototype: Selector
Noch mehr CSS Selektoren
Mit dem ‚Selector‘ kann nach Elementen gesucht werden
Ist doch das gleiche wie $$?
- Genau, plus eine spezielle Funktion
- .match() gibt an, ob ein Element dem Selektor entspricht
Und sonst?
Das Objekt ist schlecht dokumentiert, kann aber wahrscheinlich
effektiv nicht viel mehr als ein Aufruf der $$-Funktion
Prototype: Selector
Anwendung des Selector
// <div id="firstFormContainer" class="FormContainer" />
// <div id="anotherFormContainer" class="FormContainer" />
// <div id="aFormContainer" />
var Sel = new Selector('div.FormContainer');
Sel.match($('someOtherDiv')); // false
Sel.match($('firstFormContainer')); // true
// Beide obigen Container holen
var cont1 = Sel.findElements();
// Oder wenn man es in einem bestimmten div suchen will
var cont2 = Sel.findElements($('containsDivs'));
Prototype: document
Erweiterungen des document Objekts
Es wird das registrieren/abfeuern von Events ermöglicht mit den
bekannten Methoden „observe“ und „stopObserving“
Der viewport (was im Browser sichtbar ist)
document.viewport.getHeight(): Höhe des sichtbaren Bereichs
document.viewport.getWidth(): Breite des sichtbaren Bereichs
document.viewport.getScrollOffsets(): left/top Offset des Scrollbalken
Prototype: $A
Arrays casten
Hiermit kann man so gut wie alles zu einem Array casten
Warum? Weil man…
…oft eine NodeList oder eine HTMLCollection bekommt und
diese nicht mit Prototype Features erweitert werden (können)
Was kann ein Prototype Array
Basiert auf „Enumerable“ und bietet damit 44 neue Methoden
zum iterieren, suchen und arbeiten mit Arrays
Prototype: $A
Beispiel inkl. each() Funktion
var ps = $A(document.getElementsByTagName('p'));
// Nun können wir mit Each jedes Element durchgehen
ps.each(function(item) {
alert(item.innerHTML);
});
// Oder eine bestehende Funktion darauf ausführen
ps.each(Element.hide);
Prototype: Array Funktionen
Prüfen ob alle Elemente einem Wert entsprechen
// -> true (Ein leeres Array hat keine falschen Werte)
[].all();
// -> true (Alle Werte in 1 bis 5 sind true)
$R(1, 5).all();
// -> false (0 gilt als false)
[0, 1, 2].all();
// -> false (Auf 9 kommt false zurück)
[9, 10, 15].all(function(n) { return n >= 10; });
// Selbe Funktion mit "any", gibt jedoch schon bei
// einem gültigen Wert true zurück
Prototype: Array Funktionen
Funktionsauswertung aller Elemente als Array
// Gibt folgendes Array ['H', 'H', 'G']
['Hitch', "Hiker's", 'Guide'].collect(function(s) {
return(s.charAt(0).toUpperCase());
});
// Gibt alle Quadratzahlen von 1 bis 5 [1, 4, 9, 16, 25]
$R(1,5).collect(function(n) {
return(n * n);
});
Prototype: Array Funktionen
Geprüfte Werte zurück bekommen
// Wir wenden auf jedes Objekt Object.IsString an
// Alle Werte die "true" ergeben kommen als Array zurück
[1, 'two', 3, 'four', 5].filter(Object.isString);
// Resultiert daher in ['two','four']
// Wir wenden auf jedes Objekt Object.IsString an
// Alle Werte die "false" ergeben kommen als Array zurück
[1, 'two', 3, 'four', 5].reject(Object.isString);
// Resultiert daher in [1,2,3]
// Das geht auch mit eigenen Funktionen
[1, 'two', 3, 'four', 5].filter(function(item)) {
// Hier item prüfen und true/false zurückgeben
});
Prototype: Array Funktionen
Das selbe noch mit Regex
// Alle Strings mit Doppelbuchstaben finden
['hello', 'world', 'this', 'is', 'cool'].grep(/(.)1/);
// Ergibt folgendes Array: ['hello', 'cool']
// Innerhalb 1 bis 30 alle Zahlen die mit 0 oder 5
// enden holen und eins davon abziehen
$R(1, 30).grep(/[05]$/, function(n) { return(n - 1); });
// Ergibt folgendes Array: [4, 9, 14, 19, 24, 29]
Prototype: Array Funktionen
Zahl, String oder Objekt in einem Array finden
// Gibt true, da 10 im Range 1 bis 15 vorkommt
$R(1, 15).include(10);
// Gibt false, da Gross-/Kleinschreibung beachtet wird
['hello', 'world'].include('HELLO');
// Gibt true, da hello 1:1 so vorkommt
['hello', 'world'].include('hello');
// Gibt true, da 3 == '3' in JS true ergibt
[1, 2, '3', '4', '5'].include(3);
Prototype: Array Funktionen
Objektmethoden aufrufen
// Einfacher Aufruf, der Arraywert ist immer der 1. Parameter
// Resultat ergibt: ['HELLO', 'WORLD']
['hello', 'world'].invoke('toUpperCase');
// Parameter folgen dem Methodennamen
// Substring calls ergeben: ['hel', 'wor']
['hello', 'world'].invoke('substring', 0, 3);
// Stoppt den 'change' event auf allen Input Feldern
$$('input').invoke('stopObserving', 'change');
Prototype: Array Funktionen
Objektmethoden aufrufen (An eigenen Objekten)
var AddCalc = Class.create({
initialize : function(first,second) {
this.First = first;
this.Second = second;
},
Compute : function() {
return(this.First + this.Second);
}
});
[ new AddCalc(5,5), new AddCalc(8,9)].invoke('Compute');
// Ergibt folgendes Array [10, 17]
Prototype: Array Funktionen
Feldwerte lesen und als Array zurückbekommen
// Stringlänge aller Objekte herausfinden
// Gibt folgendes Array: [5, 5, 4, 2, 4]
['hello', 'world', 'this', 'is', 'nice'].pluck('length');
// checked Feld aller Checkboxen lesen
var checks = $$('input[type=checkbox]');
var values = checks.pluck('checked')
// Alles umkehren
for (i = 0;i < checks.length;i++) {
checks[i].checked = !values[i];
}
Prototype: Array Funktionen
Array Sortieren
// Nach Stringlänge sortieren
// Ergibt: ['is', 'nice', 'this', 'world', 'hello']
['hello', 'world', 'this', 'is', 'nice'].sortBy(function(s) {
return(s.length);
});
// Objekte mit internem Sortierwert sortieren
MyObjectArray.sortBy(function(s) {
// Mit „this“ könnte man hier auf das ganze Array zugreifen
return(s.GetInternalOrder());
});
Prototype: Array Funktionen
Zusammenführen von Arrays
var firstNames = ['Jane', 'Nitin'];
var lastNames = ['Doe', 'Patel'];
var ages = [23, 41];
// Ergibt: [['Jane', 'Doe'], ['Nitin', 'Patel']]
firstNames.zip(lastNames);
// Ergibt [['Jane', 'Doe', 23], ['Nitin', 'Patel', 41]]
firstNames.zip(lastNames, ages);
// Oder wir wenden eine Funktion an, um das
// resultierende Array zu beeinflussen
// Ergibt: ['Jane Doe is 23', 'Nitin Patel is 41']
firstNames.zip(lastNames, ages, function(tuple) {
return(tuple[0] + ' ' + tuple[1] + ' is ' + tuple[2]);
});
// Man kann so z.B. Objekte aus Arrays kreieren
Prototype: $H / Hash
Was ist ein Hash?
Äquivalent zu „Dictionary“ in ASP oder .NET
Zusammenfassen von Daten
Kann als alternative zu Objekten verwendet werden. Ein Hash
Hat zudem einige Hilfreiche Funktionen
Methoden des Hash
toQueryString(): Falls Post nicht möglich, Daten als Querystring
toJSON()/toObject(): Liefern beide ein Objekt für z.B. Ajax Posts
set()/get()/unset(): Kommen gleich im Codebeispiel
update(): Erweitert den Hash mit dem übergebenen Objekt
keys()/values(): Liefert entsprechende Arrays
Prototype: $H / Hash
Anwendung des Hash
var h = $H({name: 'Michael', age: 21, country: 'England'});
// Ist das selbe wie...
var h = new Hash({name: 'Michael', age: 21, country: 'England'});
// Mit "get" erhält man den entsprechenden Wert
var country = h.get('country');
// Mit "set" kann man einen neue Wert setzen oder bearbeiten
h.set('name','John');
h.set('lastname','Doe');
// Iterieren kann man auch hier mit der "each" Methode
h.each(function(pair,index) {
alert('on ' + index + ': ' + pair.key + '=' + pair.value);
});
Prototype: $R / ObjectRange
Was ist ein ObjectRange?
Ein Objekt, welches einen Range (Array) kreiert
Wozu kann man es verwenden?
Man weiss es nicht. z.B. um ein Zahle-n oder Buchstabenarray zu
erzeugen, welches man dann irgendwie weiter verwenden kann
Was kann der Range
Als erstes: Alles was eine Enumeration auch kann
include(): Überschreibt include() der Enumeration
end/start: Properties für das beginnende und endende Objekt
Prototype: $R / ObjectRange
Anwendung des Range
// Range von 1 - 10
$R(0, 10)
// Range von String aa bis ah: aa ab ac ad af ag ah
$R('aa', 'ah')
// Range von 1 bis 10 ohne letzte Zahl (Also 1 bis 9)
$R(0, 10, true).include(10)
// Range gibt eine Enumeration, man kann also each verwenden
$R(0, 10, true).each(function(value) {
alert(value);
});
Prototype: $R / ObjectRange
Anwendung des Range mit eigenem Objekt
var BigCounter = Class.create({
initialize : function(value) {
this.Value = value
},
succ : function() {
return(this.Value + 750);
}
});
// Range mit BigCountern: 1500, 2250 ... 6000, 6750
$R(new BigCounter(1500),new BigCounter(6750));
Prototype: Funktionserweiterungen
Methoden für Funktionen
Prototype erweitert die Funktionsreferenzen automatisch
Hier kommt Magie zum Einsatz
Das gibt‘s sonst nirgendwo: Deferier- und delaybare Aufrufe,
Parametererweiterungen und Methodisierung
Prototype: Funktionserweiterungen
Parameternamen herausfinden
// Funktion. (Das alles geht auch mit Objektmethoden)
function add(first, second) {
return(first + second);
}
// Array der Argumente holen: ['first', 'second']
add.argumentNames();
Prototype: Funktionserweiterungen
Kontext binden (Wichtig für OOP implementationen)
var AlertOnClick = Class.create({
initialize: function(msg) {
this.msg = msg;
// Klappt nicht, da Events „kontextlos“ sind
$('submit').observe('click', this.Click);
// Klappt, da der Objektkontext übergeben wird
$('submit').observe('click', this.Click.bind(this));
},
Click: function(event) {
event.stop();
$('message').update(this.msg).show();
}
});
Prototype: Funktionserweiterungen
Parametererweiterung (Do it the indian way)
function showArgs() {
// 'arguments' ist ein Array aller Paremter
alert($A(arguments).join(', '));
}
// Liste der Parameter ausgeben: '1, 2, 3'
showArgs(1,2,3);
// Mit Curry eine Funktionskopie erstellen, welche
// Die Funktion mit Default 1,2,3 aufruft
var showExtended = showArgs.curry(1,2,3);
// Diese mit weitere Parametern aufrufen: '1, 2, 3, a, b'
showExtended('a','b');
Prototype: Funktionserweiterungen
Deferieren (Verschieben ans Ende)
// Funktionen die mit "defer" aufgerufen werden, wird der
// Interpreter erst Ausführen wenn er nichts mehr zu tun hat
function showMsg(msg) {
alert(msg);
}
showMsg("One"); // Normaler Aufruf
showMsg.defer("Two"); // Verschobener Aufruf
showMsg("Three"); // Normaler Aufruf
// Output: One, Three, Two
Prototype: Funktionserweiterungen
Klassisches Beispiel (defer Methode)
// Klassiker, den man immer wieder sieht:
var Assistant = Class.create({
function : initialize() {},
// Funktion die ein Control per Effekt einblendet
function : ShowInput(ele) {
$(ele).appear({ duration: 3.0 });
// 1. Nicht im Objekt Kontext, 2. Unschön
setTimeout('MyObject.DoSomething()',3000);
},
// Funktion die nach dem Effekt aufgerufen werden soll
function : DoSomething() {}
});
Prototype: Funktionserweiterungen
Klassisches Beispiel (defer Methode)
var Assistant = Class.create({
function : initialize() {},
// Funktion die ein Control per Effekt einblendet
function : ShowInput(ele) {
$(ele).appear({ duration: 3.0 });
// 1. Im Objektkontext, 2. Optimal, da am Funktionsende.
// Wird ausgeführt wenn der Interpreter idle ist, und das
// ist er zufälligerweise erst, wenn der Effekt beendet ist
this.DoSomething.defer();
},
// Funktion die nach dem Effekt aufgerufen werden soll
function : DoSomething() {}
});
Prototype: Funktionserweiterungen
Delayen (Verschieben auf fixen Zeitpunkt)
// Ist defer nicht sicher genug, geht es immer noch so
var Assistant = Class.create({
function : initialize() {},
// Funktion die ein Control per Effekt einblendet
function : ShowInput(ele) {
$(ele).appear({ duration: 3.0 });
// Funktonsaufruf gleich wie Effekt delayen
this.DoSomething.delay(3.0);
},
// Funktion die nach dem Effekt aufgerufen werden soll
function : DoSomething() {}
});
Prototype: Funktionserweiterungen
Delayen mit Parameter
var Assistant = Class.create({
function : initialize() {},
// Funktion die ein Control per Effekt einblendet
function : ShowInput(ele) {
$(ele).appear({ duration: 3.0 });
// Erst das Timeout, dann die Parameter
this.DoSomething.delay(3.0, 'hello', 'world');
},
// Funktion die nach dem Effekt aufgerufen werden soll
function : DoSomething(param1, param2) {}
});
Prototype: Funktionserweiterungen
Methodisierung (Statische Funktionen an Objekte binden)
// Funktion, die auf ein Objekt, das "name" Prop. setzt
function setName(target, name) {
target.name = name;
}
// Kann man z.B. so ohne Kontext verwenden
object = {};
setName(object, 'Fred');
// Man kann aber auch das Objekt "Methodisieren"
obj.setName = setName.methodize();
// "target" ist nun "this" und wird direkt angewendet
obj.setName('Barney');
// Prototype setzt dies für fast alle Funktionen ein
Prototype: Funktionserweiterungen
Bestehende Methoden erweitern
// capitalize Funktion mit einem Parameter erweitern
String.prototype.capitalize = String.prototype.capitalize.wrap(
function(OriginalMethod, eachWord) {
if (eachWord && this.include(" ")) {
// Wenn Parameter (true), jedes Wort kapitalisieren
return(this.split(" ").invoke("capitalize").join(" "));
} else {
// Oder die bisherige Standarmethode anwenden
return(OriginalMethod());
}
}
);
"hello world".capitalize(); // "Hello world"
"hello world".capitalize(true); // "Hello World"
Prototype: Number Methoden
Erweiterung von „Math“
Number vereint Math und mehr
Beispiele
- Fügt für jede Zahl abs(), ceil, floor(), und round() hinzu
- toColorPart(): Gibt die Hex Version einer Zahl zurück
- toPaddedString(n): Gibt den Zahlenwert mit führenden Nullen zurück
Prototype: The Object Object
Wer profitiert davon
Alle primitiven Datentypen, alle Objekte, selbst Eigenbauten
Hilfreiche Funktionen
- clone(): Erzeugt eine Shallow Copy. Deep Copy umsetzbar
- extend(): Erweitert ein bestehendes Objekt
- inspect(): Gibt Debug-Informationen des Objekts aus
- Anwendbar statisch oder im Objektkontext als Methode
Validierung
Validierung (Nur statisch) kann nicht schaden: isArray(), isElement(),
isFunction(), isHash(), isNumber(), isString(), isUndefined().
Prototype: PeriodicalExecuter
Warum nicht setInterval?
Weil die Ausführungszeit dort nicht eingerechnet ist
Und sonst?
- Die stop() Methode haltet den Executer an
- Geeigneter für OOP da Kontextübergabe möglich
Prototype: PeriodicalExecuter
Simpler Aufruf
// Übergabe einer direkten Funktion
new PeriodicalExecuter(function(executer) {
if (!confirm('Hey bananas, what'cha doin'?')) {
executer.stop();
}
}, 5.0);
// Verwendung innerhalb eines Objekts
this.Exec = new PeriodicalExecuter(this.DoIt.bind(this),5.0);
// Funktion DoIt als Beispiel
DoIt : function(pe) {
pe.stop(); // Übergebenen Executer stoppen
this.Exec.stop(); // Oder die Objektreferenz, da Kontext
}
Prototype: Prototype.Browser
Der Prototype Namespace
Bietet nicht viel gescheites ausser „Browser“
Ein Set von Booleans
Wenns mal doch nicht klappt: Prototype.Browser
.IE: Check ob IE vorhanden (Zudem: IE6, IE7, IE8)
.Opera: Check auf jegliche Versionen von Opera
.WebKit: Check auf Webkit Browser (Safari, Anroid)
.MobileSafari: Expliziter Check auf iPhone Browser
.Gecko: Browser basierend auf Gecko (Firefox, Netscape)
Prototype: String
Sind wir nicht endlich durch?
Nein. Mit dem String Objekt kommt nochmal eine grobe Sache
Gültigkeit der Methoden
Jeder String besitzt die neuen Methoden, da Prototype direkt
das String Objekt erweitert (Wie bei Zahlenwerten)
Wichtige Funktionen
.capitalize(): Ersten Buchstaben gross schreiben
.endsWith()/startsWith(): Start oder Ende des Strings prüfen
.(un)escapeHtml(): Konvertiert reinen Text in HTML Entitäten und zurück
Prototype: String
Noch etwas mehr Funktionen
.evalJSON(): JSON String zu einem Objekt konvertieren
.isJSON(): Gibt an, ob der String evaluierbares JSON enthält
.evalScripts(): Javascript Code innerhalb des Strings ausführen
.extractScripts(): Gibt ein Array aller Javascript Codezeilen zurück
.sub()/.gsub(): Einfache Form von Regex und/oder Replace
.scan(): Erlaubt die Anwendung eines Callback für jeden Teilstring
.stripScripts(): Löscht alle <script> Tags und JS Codes aus dem String
.stripTags(): Entfernt alle HTML Tags aus dem String
.toArray(): Erstellt ein Char Array aus dem String
.toQueryParams(): Erstellt JSON Code aus URL Parametern
.truncate(): Kürzt den String auf X-Zeichen und fügt Suffix an
Prototype: Template
Sowas wie String.Format in .NET
String mit Variablen durch Objektproperties ersetzen
Gedacht für mehrfache Verwendung
Das Template ist z.B. für Listenansichten sehr geeignet, lässt aber
auch herkömmlichen „Verknüpfungscode“ schöner aussehen
Wichtige Funktionen
.evaluate(obj): Ersetzt die Templatevariablen mit entsprechenden
Variablen im gegebenen Objekt (JSON oder Prototype Objekt)
Prototype: PeriodicalExecuter
Anwendung des Template
var conv1 = { from: 'meters', to: 'feet', factor: 3.28 };
var conv2 = { from: 'kilojoules', to: 'BTUs', factor: 0.9478 };
var conv3 = { from: 'megabytes', to: 'gigabytes', factor: 1024 };
// Template erstellen
var tpl = new Template(
'Multiply by #{factor} to convert from #{from} to #{to}.'
);
// Alle formatieren... mit on-the-fly-array-each :D
[conv1, conv2, conv3].each(function(conv){
tpl.evaluate(conv);
});
// -> Multiply by 3.28 to convert from meters to feet.
// -> Multiply by 0.9478 to convert from kilojoules to BTUs.
// -> Multiply by 1024 to convert from megabytes to gigabytes.
Inhalte Scriptaculous
Effekte
Effektbeispiele, Queues, Combination, Toggle
Controls
Slider, Sortable(s), Ghostly, Test.Unit
Ajax
Autocompleter, In Place Editing
Scriptaculous: Effekte
Zurück zum Kerngeschäft
Scriptaculous bietet Effekte und Controls
Warum bietet Prototype das nicht an?
Prototype und Scriptaculous haben eine strikte Trennung aus
funktionalem Framework und Effekten/Controls
Effekttypen
Es wird zwischen Kerneffekten und Kombinationseffekten unterschieden
Scriptaculous: Effektbeispiele
Anzeige-Effekte
Effect.Highlight: Lässt die Hintergrundfarbe kurz aufblinken
Effect.Morph: Erlaubt Farbwechsel zwischen zwei Farben
Effect.Move: Absolute oder Relative Veränderung der Position
Erschein-Effekte
Effect.Appear: Sanftes Einblenden eines Controls
Effect.BlindDown: Herunterfahren eines Controls
Ausblende-Effekte
Effect.Fade: Sanftes ausblenden eines Controls
Effect.BlindUp: Herauffahren eines Controls
Scriptaculous: Effekt Queues
Effect.Queue
Jeder Effekt lässt sich in eine Queue stellen, da er ansonsten
parallel mit anderen Effekten ausgeführt würde
Einschränkung
Man muss eindeutige „Scopes“ definieren, um Sie während der
Laufzeit mit Effect.Queue steuern (z.B. Abbrechen) zu können
Beispiel
Das folgende Beispiel zeigt die Grundlegende Arbeit mit Queues.
Merke: Queues sind nur nötig, wenn Effekte auf dem selben Element
nacheinander anstatt gleichzeitig ausgeführt werden sollen
Scriptaculous: Effekt Queues
Erstellen von Queues
// Menu anzeigen, ans Ende des 'sc_menu' Scope
new Effect.SlideDown('menu',
{ queue: { position: 'end', scope: 'sc_menu' } }
);
// Banner anzeigen, ans Ende des 'sc_banner' Scope
new Effect.Appear('bannerbig',
{ queue: { position: 'end', scope: 'sc_banner' } }
);
// Menu pulsieren lassen, nach SlideDown Effekt
new Effect.Pulsate('menu',
{ queue: { position: 'end', scope: 'sc_menu' } }
);
Scriptaculous: Effekt Queues
Steuern der Scopes
// z.B. die Menu Queue holen
var queue = Effect.Queues.get('sc_menu');
// 'queue' ist eine Prototype Enumeration, daher...
queue.each(function(effect) { effect.cancel(); });
// ... um alles abzubrechen oder ...
queue.invoke('cancel');
// …Wartezeit zwischen Effekten beeinflussen
queue.interval = 100;
Scriptaculous: Combination / Toggle
Combinations toggeln und mergeln
SlideUp()/Down(), Appear()/Fade() und BlindDown()/Up() lassen sich mit
toggle() einfach kombinieren bzw. ein- und ausblenden
Sinn dahinter
Spart einiges an Code, da ein-/ausblenden mit einer
Zeile Code realisiert werden kann
Questions
Aufwachen!
Ihr habt‘s hinter euch.

Mais conteúdo relacionado

Mais procurados

Genügend gute Gründe, wieso Ruby besser als PHP ist
Genügend gute Gründe, wieso Ruby besser als PHP istGenügend gute Gründe, wieso Ruby besser als PHP ist
Genügend gute Gründe, wieso Ruby besser als PHP ist
Daniel Spangenberg
 

Mais procurados (16)

Do while
Do whileDo while
Do while
 
Mvc public
Mvc publicMvc public
Mvc public
 
P6oo
P6ooP6oo
P6oo
 
Perl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz EditionPerl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz Edition
 
JavaScript Performance
JavaScript PerformanceJavaScript Performance
JavaScript Performance
 
Einführung in React
Einführung in ReactEinführung in React
Einführung in React
 
An Introduction to Ruby
An Introduction to RubyAn Introduction to Ruby
An Introduction to Ruby
 
JavaScript Performance
JavaScript PerformanceJavaScript Performance
JavaScript Performance
 
OpenLDAP - A developer's perspective
OpenLDAP - A developer's perspectiveOpenLDAP - A developer's perspective
OpenLDAP - A developer's perspective
 
Was geht mit Java 17?
Was geht mit Java 17?Was geht mit Java 17?
Was geht mit Java 17?
 
Php Schulung
Php SchulungPhp Schulung
Php Schulung
 
Ruby is Magic - Episode #7: Closures
Ruby is Magic - Episode #7: ClosuresRuby is Magic - Episode #7: Closures
Ruby is Magic - Episode #7: Closures
 
Drupal 8: TWIG Template Engine
Drupal 8:  TWIG Template EngineDrupal 8:  TWIG Template Engine
Drupal 8: TWIG Template Engine
 
PHP: exit
PHP: exitPHP: exit
PHP: exit
 
Genügend gute Gründe, wieso Ruby besser als PHP ist
Genügend gute Gründe, wieso Ruby besser als PHP istGenügend gute Gründe, wieso Ruby besser als PHP ist
Genügend gute Gründe, wieso Ruby besser als PHP ist
 
Perl 5.20: Feature, Kultur, Module, Werkzeuge
Perl 5.20: Feature, Kultur, Module, WerkzeugePerl 5.20: Feature, Kultur, Module, Werkzeuge
Perl 5.20: Feature, Kultur, Module, Werkzeuge
 

Destaque (6)

eliminato il software e-mail di recupero
eliminato il software e-mail di recupero eliminato il software e-mail di recupero
eliminato il software e-mail di recupero
 
Lip plumper gloss
Lip plumper glossLip plumper gloss
Lip plumper gloss
 
Deporte2
Deporte2Deporte2
Deporte2
 
Adserver
AdserverAdserver
Adserver
 
Bio Scope
Bio ScopeBio Scope
Bio Scope
 
Linked in overview slideshare
Linked in overview slideshareLinked in overview slideshare
Linked in overview slideshare
 

Semelhante a Prototype 1.7

Agiles Modellieren mit Domain Specific Languages
Agiles Modellieren mit Domain Specific LanguagesAgiles Modellieren mit Domain Specific Languages
Agiles Modellieren mit Domain Specific Languages
Dominik Hirt
 
Creasoft - Windows powershell
Creasoft - Windows powershellCreasoft - Windows powershell
Creasoft - Windows powershell
Creasoft AG
 
Dojo Und Notes
Dojo Und NotesDojo Und Notes
Dojo Und Notes
dominion
 

Semelhante a Prototype 1.7 (20)

Testing tools
Testing toolsTesting tools
Testing tools
 
Agiles Modellieren mit Domain Specific Languages
Agiles Modellieren mit Domain Specific LanguagesAgiles Modellieren mit Domain Specific Languages
Agiles Modellieren mit Domain Specific Languages
 
A/B Testing mit Node.js
A/B Testing mit Node.jsA/B Testing mit Node.js
A/B Testing mit Node.js
 
Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010
 
node.js
node.jsnode.js
node.js
 
Node.js Security
Node.js SecurityNode.js Security
Node.js Security
 
TypeScript
TypeScriptTypeScript
TypeScript
 
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
 
Warum ECMAScript 6 die Welt ein Stückchen besser macht
Warum ECMAScript 6 die Welt ein Stückchen besser machtWarum ECMAScript 6 die Welt ein Stückchen besser macht
Warum ECMAScript 6 die Welt ein Stückchen besser macht
 
jQuery & CouchDB - Die zukünftige Webentwicklung?
jQuery & CouchDB - Die zukünftige Webentwicklung?jQuery & CouchDB - Die zukünftige Webentwicklung?
jQuery & CouchDB - Die zukünftige Webentwicklung?
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
 
Besseren Java Code mit Type Annotations
Besseren Java Code mit Type AnnotationsBesseren Java Code mit Type Annotations
Besseren Java Code mit Type Annotations
 
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
 
Modern angular 02_angular_mit_type_script
Modern angular 02_angular_mit_type_scriptModern angular 02_angular_mit_type_script
Modern angular 02_angular_mit_type_script
 
jQuery Kurz-Intro
jQuery Kurz-IntrojQuery Kurz-Intro
jQuery Kurz-Intro
 
Creasoft - Windows powershell
Creasoft - Windows powershellCreasoft - Windows powershell
Creasoft - Windows powershell
 
Übersicht Skriptsprachen
Übersicht SkriptsprachenÜbersicht Skriptsprachen
Übersicht Skriptsprachen
 
Speeding up Java Persistence
Speeding up Java PersistenceSpeeding up Java Persistence
Speeding up Java Persistence
 
Backend-Services mit Rust
Backend-Services mit RustBackend-Services mit Rust
Backend-Services mit Rust
 
Dojo Und Notes
Dojo Und NotesDojo Und Notes
Dojo Und Notes
 

Prototype 1.7

  • 2. Inhalte Prototype Ajax Responders, Response, Request, (Periodical)Updater DOM JSON, $, $F, Abstract, Element, Form, document Spracherweiterungen Weitere $‘s, Array, Class, Date, Function, Object, String, Template, Enumerable, RegExp, Prototype/Try
  • 3. Prototype: Ajax.Responders Funktion Globale Events/Callbacks für alle Ajax Requests Registration Ajax.Responders.register/unregister Callbacks onCreate, onComplete, onException
  • 4. Prototype: Ajax.Responders Herkömmlicher Ajax Responder Ajax.Responders.register({ onCreate: function(request,XmlHttpRequest,Json) { alert('new request registered'); Ajax.activeRequestCount++; }, onComplete: function(request,XmlHttpRequest,Json) { alert('request has ended'); Ajax.activeRequestCount--; } });
  • 5. Prototype: Ajax.Request Funktion Gewöhnlicher Ajax Request Wichtige Optionen asynchronous = true: (A)synchrone Anfrage contentType: Ändern wenn man z.B. XML senden will encoding = UTF8: Falls es mal Probleme mit Kodierung gibt parameters: Parameter im URL oder JSON Format Wichtige Callbacks onFailure: Wird bei HTTP Errors geworfen 40x – 50x onSuccess: Kommt zum Zug bei 20x Statuscodes
  • 6. Prototype: Ajax.Request JSON Antwortobjekt var data = {}; data.getres = 1001; data.language = SV_LANG_DE; data.isIE = true; new Ajax.Request('/pfad/zum/script/?id=685', { parameters : data, method : 'post', onSuccess: function(response) { var json = response.responseText.evalJSON(); alert('Antwort: ' + json.message); } });
  • 7. Prototype: Ajax.Request Synchroner Request var data = {}; data.getres = 1001; data.language = SV_LANG_DE; data.isIE = true; var myRequest = new Ajax.Request('/service/class/getres/', { parameters : data, method : 'post', asynchronous : false }); alert(myRequest.transport.responseText);
  • 8. Prototype: Ajax.Response Funktion Antwortobjekt eines Ajax.Request Wichtige Properties responseText: Text der Ajax Antwort responseXML: XMLDOM Objekt, wenn application/xml Header responseJSON: JS Objekt, wenn application/json Header transport: Zugriff auf das Native XmlHttpRequest Objekt
  • 9. Prototype: Ajax.Updater Funktion Updatet einen Container, erbt von Ajax.Request Und wozu ist das gut? - Vereinfachung eines oft verwendeten Use-Case - Verwendet das verhalten von Element.update() Zusätzliche Properties evalScripts = false: Führt Code in <script> Tags aus insertion: Mögliche Werte: top, bottom, before, after -> Mehr dazu bei den Element Methoden
  • 10. Prototype: Ajax.Updater Codebeispiel <script type="text/javascript"> function UpdateChat() { new Ajax.Updater( { success: 'chatWindow' }, '/getmessage/?chat=45764', { insertion: 'top‚ } ); setTimeout('UpdateChat()',1000); } UpdateChat(); </script> <div id="chatWindow"></div>
  • 11. Prototype: Ajax.PeriodicalUpdater Funktion Wie Updater, führt sich aber periodisch selbst wieder aus Wichtige Optionen frequency = 2: Warten zwischen Abfragen decay = 1: Erhöht die Rate von frequency, wobei der übergebene Wert ein Multiplikator ist. 1 Hat daher keine Wirkung, 2 z.B. verdoppelt den Wert von frequency. Wenn Resultat !=, wird frequency zurückgesetzt. Nutzen - Sehr wenig Code nötig für automatische Updater - Spart Ressourcen durch den decay Parameter
  • 12. Prototype: Ajax.PeriodicalUpdater Codebeispiel <script type="text/javascript"> new Ajax.PeriodicalUpdater( { success: 'chatWindow'‚ failure : 'errorMsg' }, '/getmessage/?chat=34756', { insertion: 'top', frequency: 2 } ); </script> <div id="chatWindow"></div> <div id="errorMsg"></div>
  • 13. Kurze Einführung: JSON Wer ist Jason? Die Javascript Object Notation Wozu wird es verwendet? - Objektorientiertes Javascript - Interner Datenaustausch (z.B. Funktionsparameter) - Externer Datenaustausch (z.B. Ajax) Syntax Properties, Arrays, Objektarrays, Funktionen… … mit relativ wenig Zeichen (Leichtgewichtig)
  • 14. Kurze Einführung: JSON Einfache Daten und Arrays var object = { message : 'this is json', really : true, howmany : 1337, inner : { value : 'inneres objekt', great : false }, array : [ 1,2,3,4,5,6,7,8 ], strings : [ 'hello', 'world' ] };
  • 15. Kurze Einführung: JSON Objektarrays (Einfaches verschachteln) var object = { objectarray : [ { message : 'this is json', really : true }, { message : 'this is xml', really : false }, { message : 'this is asp', really : false } ], additional : 'hello world' };
  • 16. Kurze Einführung: JSON Funktionen (Dazu mehr unter „Klassen“) var Calculator = { Add : function(param1,param2) { return(param1 + param2); }, Subtract: function(param1,param2) { return(param1 – param2); }, };
  • 17. Prototype: $... Die Funktion Funktion Alias für document.getElementById und mehr Wie mehr? $(‘eleID‘) gibt ein Element zurück $(‘eleID‘,‘inputID‘,‘textID‘) gibt ein Array zurück DOM der Elemente wird erweitert (Dazu gleich mehr) Nutzen Effizienter / besser lesbarer Code
  • 18. Prototype: $... Die Funktion Typischer Code einer Validierungsroutine // Validierbares Element holen var ele = document.getElementById('eleID'); // Array von Werten für For basteln var some = []; some[0] = document.getElementById('eleID'); some[1] = document.getElementById('inputID'); some[2] = document.getElementById('textID'); // Error Message Divs ausblenden document.getElementById('errorMessage').style.display = 'none'; document.getElementById('errorDiv').style.display = 'none';
  • 19. Prototype: $... Die Funktion Typischer Code gleicher Code mit Prototype // Validierbares Element holen var ele = $('eleID'); // Array von Werten für For-Schlaufe var some = $('eleID','inputID','textID'); // Mit „hide“ Funktion auf allen Elementen, Divs ausblenden $('errorMessage','errorDiv').invoke('hide'); Anmerkung: Die hide() und show() Methode ist nur eine der zahlreichen DOM Erweiterungen die jedes Element bekommt
  • 20. Prototype: Geht‘s noch schneller? Eine Nanosekunde effizienter Ja, mit der $F() Methode Formularwert holen Erwartet eine ID als Wert, und gibt den Wert des dahinter liegenden Formularfeldes mit der getValue() Methode zurück. $(‘example‘).getValue() Gleich wie .value Property ausser bei Multiselect, da kommt immer ein Array zurück
  • 21. Prototype: Geht‘s noch schneller? Schnell ein Formular speichern var Assistant = Class.create(); Assistant.prototype = { Save : function() { new Ajax.Request('/admin/content/?id=324', method : 'post', parameters : { 'Name' : $F('Name'), 'Firstname' : $F('Firstname'), 'Email' : $F('Email') } ); } };
  • 22. Prototype: Klassen Objektbasiert? Orientiert, wir können Abstrakt. Wie kann man vorgehen - Klasse leer erstellen und Body erweitern - Klasse direkt vollständig ausprogrammieren Eigenheiten Klassendefinitionen sind zur Laufzeit erweiterbar (Für alle Instanzen) Statische Properties kennt Javascript nicht Public, Private, Protected? Umsetzbar, aber kein Bestandteil
  • 23. Prototype: Klassen Erstellen und erweitern… var Assistant = Class.create(); Assistant.prototype = { // Konstruktor initialize : function() { }, // Speicherfunktion Save : function() { alert('data saved'); } };
  • 24. Prototype: Klassen …oder direkt ausprogrammieren var Assistant = Class.create({ // Konstruktor initialize : function(id) { // Hier sind meist window.onload/dom:loaded Events }, // Speicherfunktion Save : function() { alert('data saved'); } });
  • 25. Prototype: Klassen Erben des einer Klasse var BetterAssistant = Class.create(Assistant,{ // Konstruktor initialize : function($super,id) { // Parent Methode aufrufen, geht bei allen überschriebenen $super(id); }, // Speicherfunktion überschreiben Save : function($super) { this.Validate(); // Erst validieren $super(); } });
  • 26. Prototype: Klassen Methoden überschreiben (Clean way) BetterAssistant.addMethods({ // Speichern geht noch besser Save : function($super) { // Validieren und speichern $super(); // Meldung an User geben this.Notify(); }, // Meldung an User Notify : function() { $('message').update('Daten gespeichert!'); $('message').show(); } });
  • 27. Prototype: Element Erweiterungen Wie bekomme ich die Erweiterungen Mit Element.method() oder $(‘someElement‘).method() Einige Beispiele - Element.update(): Ein Block Element verändern - Element.setStyle()/getStyle(): CSS, Browserkompatibel - Element.show()/hide()/toggle(): Anstatt direkt CSS zu modifizieren - Element.absolutize()/relativize(): Element Positionstyp ändern - Element.removeClassName()/addClassName(): Sprechend - Und 76 weitere Methoden Welche wir hier finden Gibt es hier: http://api.prototypejs.org/dom/element/
  • 28. Prototype: Element Erweiterungen Element.update() - Beispiel var html = '<p>Gleich passiert was<p>' + '<script type="text/javascript">' + ' alert("sehen sie?");' + '</script>'; $('message').update(html);
  • 29. Prototype: Element Erweiterungen Anwendung der toString() Methode mit Element.Update() var Fruit = Class.create({ initialize : function(name) { this.Name = name; } toString: function() { return('Hey ' + this.Name + '! I'm an orange.'); } }); var apple = new Fruit('apple'); $('fruits').update(apple); $('fruits').innerHTML;
  • 30. Prototype: Element Erweiterungen Klassen hinzufügen oder entfernen <div id="msg" class="float left invisible">&nbsp;</div> <script type="text/javascript"> $('msg').addClassName('visible','error'); $('msg').removeClassName('invisible'); // -> float left visible error // -> toggleClassName(cssClass) </script>
  • 31. Prototype: Element Erweiterungen XML Arbeit vereinfachen <ul id="apples"> <li>Mutsu</li> </ul> <script type="text/javascript"> $('apples').firstChild.innerHTML; // -> undefined $('apples').cleanWhitespace(); $('apples').firstChild.innerHTML; // -> 'Mutsu' </script>
  • 32. Prototype: Element Erweiterungen Elementinhalt Erweitern oder umranden // Paragraph in ein Element einbauen $('element').insert('<p>HTML to append</p>'); // Fügt über den Paragraphen ein Bild ein $('element').insert({ top: Element('img', {src: 'logo.png'}) }); // Fügt vor und nach dem Element ein HR ein $('element').insert({ before: '<hr>', after: '<hr>' });
  • 33. Prototype: Element Erweiterungen Element bzw. Object.inspect() $('element').inspect(); // -> <div id="element" class="hello world"> Object.inspect(); // -> 'undefined' Object.inspect(null); // -> 'null' Object.inspect(false); // -> 'false' Object.inspect([1, 2, 3]); // -> '[1, 2, 3]' Object.inspect('hello'); // -> "'hello'"
  • 34. Prototype: Element.Layout Wozu Verschiedene Grössen/Abstände eines Elements lesen Vorteile - Geht auch, wenn alles in CSS definiert ist - Umgeht die Tendenz, dass Browser inkorrekte Werte liefern - Umgeht den Quirksmodus, welcher meist gar nichts liefert - Umgeht die Schwierigkeit mit unsichtbaren Elementen Vorsicht Da Resourcenintensiv sind die Werte gecached!
  • 35. Prototype: Element.Layout Instanz des Layout Objekts holen // Mit der Element Methode verwenden layout = new Element.Layout(element); // Als Instanzmethode eines Elements layout = $('element').getLayout(); // Wert lesen, CSS Version ausgeben var pl = layout.get('padding-left'); var css = layout.toCSS();
  • 36. Prototype: Element.Layout Weitere Properties height, width top, left, right, bottom border-left, border-right,border-top, border-bottom padding-left, padding-right, padding-top, padding-bottom margin-top, margin-bottom, margin-left, margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height
  • 37. Prototype: Event Objekt Events: Ein geordnetes Chaos Error 10050, too many nerves wasted Vorteile - Einfache Eventregistration - Einheitliche KEY_ Konstanten - Einheitliches Event-Daten Objekt - Diverse Helper Methoden
  • 38. Prototype: Event Objekt KEY_ Konstanten KEY_BACKSPACE, KEY_TAB, KEY_RETURN, KEY_ESC, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN, KEY_DELETE, KEY_HOME, KEY_END, KEY_PAGEUP, KEY_PAGEDOWN, KEY_INSERT
  • 39. Prototype: Event Objekt Standard Event registrieren function SomeFunction(event) { // Event ist immer "event", auch im IE! // Dieses Event Objekt ist ebenfalls erweitert } Event.observe(window, 'load', SomeFunction); $(window).observe('load', SomeFunction); $('element').observe('click', SomeOtherFunction);
  • 40. Prototype: Event Objekt Events löschen // Genau einen Event löschen, Handler muss übergeben werden Element.stopObserving(element,'click',SomeFunction); $('element').stopObserving('click',SomeFunction); // Alle Events eines Typs löschen (Keinen Handler übergeben) Element.stopObserving(element,'blur'); $('element').stopObserving('blur'); // Oder komplett alle Event entfernen Element.stopObserving(element); $('element').stopObserving();
  • 41. Prototype: Event Objekt Intelligente Events (Mit Daten) function SomeFunction(event,param) { if (event.keyCode == KEY_RETURN) { alert('daten sind: ' + param); } } $(window).observe('keydown',function(event) { SomeFunction(event,$('content').getValue()); });
  • 42. Prototype: Event Objekt Do it the OOP way var AssistantClass = Class.create({ initialize : function() { this.Input = $('myInput'); this.WeWillUseThatLater = 'Hello World'; this.Input.observe('blur',this.Validate.bind(this)); }, Validate : function(event) { // Das Event wird im Objekt Kontext ausgeführt alert(this.WeWillUseThatLater); } });
  • 43. Prototype: Event Extensions Erweiterungen am Event Objekt Alle registrierten Events liefern ein modifiziertes ‚event‘ zurück Beispiele - event.element(): Das Element auf dem der Event ausgeführt wurde - event.findElement(): Findet Objekte innerhalb des Event Elements - event.pointerX/Y(): Für Maus Events, immer absoluter Pixelwert! - event.is[Left|Right|Middle]Click(): Wie genau wurde geklickt?
  • 44. Prototype: CSS Selektoren Exkursion zu $$ Damit holen wir alles was mit CSS zu holen ist Syntax Beispiele $$(‘div.myclass‘): Alle Divs mit der Klasse myclass $$(‘.myclass‘): Alle Elemente mit der Klasse myclass $$(‘.myclass .error‘): Alle Elemente mit myclass und error $$(‘#mydiv‘): Element mit der ID mydiv $$(‘#mydiv input[type=checkbox]‘): Alle Checkboxen in #mydiv $$(‘:checked‘): Alle ausgewählten Elemente. Weitere, :disabled :enabled $$(‘#mytable tr:nth-child(even)‘): Alle geraden Zeilen von #mytable …Und alles weitere was bis und mit CSS3 möglich ist!
  • 45. Prototype: CSS Selektoren Alle Checkboxen markieren $$('#mycheckerdiv input[type=checkbox]').each(function(f) { f.checked = true; }); Schöne Tabelle bauen $$(‘#mytable tr:nth-child(even)‘).each(function(tr) { tr.className = 'AdminTabRowDark'; }); $$(‘#mytable tr:nth-child(odd)‘).each(function(tr) { tr.className = 'AdminTabRowLight'; });
  • 46. Prototype: Event.Handler Zurück bei den Events Diese arbeiten auf Wunsch auch mit Selektoren Wozu ein weiterer Handler - Der Event.Handler delegiert an Unterelemente - Delegation des Callback erfolgt über CSS Selektoren
  • 47. Prototype: Event.Handler Einen Event Handler definieren function SaveForm(event) { // Formular per Prototype Ajax Post speichern event.element.request(); } // Speichern aller "saveable" Forms, beim verlassen der Seite observer = new Event.Handler( window, // Auf das Window hören 'unload', // Wenn es verlassen wird 'form.saveable', // Alle Forms mit "saveable" Klasse SaveForm // SaveForm Methode ausführen ); observer.start();
  • 48. Prototype: Der Form Namespace Auch die Forms sind erweitert …Sofern diese mit der $-Funktion geladen werden Einige Methoden im Überblick - $(‘frm‘).disable(): Deaktiviert alle Formularelemente - $(‘frm‘).enable(): Aktiviert alle Formularelemente - $(‘frm‘).getElements(): Array aller Formularelemente - $(‘frm‘).getInputs(type): Gibt z.B. alle Checkboxen eines Forms zurück - $(‘frm‘).request(): Formular per Ajax Posten/Requesten - $(‘frm‘).serialize(true): Formular Daten als JSON oder Query holen
  • 49. Prototype: Der Form Namespace Und sonst? …nur einige Convenience Methoden Form.Observer - Trackt Änderungen in einem Formular - Kann für generische Validation verwendet werden Form.Element.Observer - Gleich wie Form.Observer, auf ein einzelnes Element - Explizite automatische Validation eines Feldes
  • 50. Prototype: Der Form Namespace Beispiele von Form(.Element).Observer // Formular alle 500ms prüfen new Form.Observer(myFrm, 0.5, GenericValidation); // Formularelement alle 300ms prüfen new Form.Element.Observer(myEle, 0.3, ExplicitValidation);
  • 51. Prototype: Selector Noch mehr CSS Selektoren Mit dem ‚Selector‘ kann nach Elementen gesucht werden Ist doch das gleiche wie $$? - Genau, plus eine spezielle Funktion - .match() gibt an, ob ein Element dem Selektor entspricht Und sonst? Das Objekt ist schlecht dokumentiert, kann aber wahrscheinlich effektiv nicht viel mehr als ein Aufruf der $$-Funktion
  • 52. Prototype: Selector Anwendung des Selector // <div id="firstFormContainer" class="FormContainer" /> // <div id="anotherFormContainer" class="FormContainer" /> // <div id="aFormContainer" /> var Sel = new Selector('div.FormContainer'); Sel.match($('someOtherDiv')); // false Sel.match($('firstFormContainer')); // true // Beide obigen Container holen var cont1 = Sel.findElements(); // Oder wenn man es in einem bestimmten div suchen will var cont2 = Sel.findElements($('containsDivs'));
  • 53. Prototype: document Erweiterungen des document Objekts Es wird das registrieren/abfeuern von Events ermöglicht mit den bekannten Methoden „observe“ und „stopObserving“ Der viewport (was im Browser sichtbar ist) document.viewport.getHeight(): Höhe des sichtbaren Bereichs document.viewport.getWidth(): Breite des sichtbaren Bereichs document.viewport.getScrollOffsets(): left/top Offset des Scrollbalken
  • 54. Prototype: $A Arrays casten Hiermit kann man so gut wie alles zu einem Array casten Warum? Weil man… …oft eine NodeList oder eine HTMLCollection bekommt und diese nicht mit Prototype Features erweitert werden (können) Was kann ein Prototype Array Basiert auf „Enumerable“ und bietet damit 44 neue Methoden zum iterieren, suchen und arbeiten mit Arrays
  • 55. Prototype: $A Beispiel inkl. each() Funktion var ps = $A(document.getElementsByTagName('p')); // Nun können wir mit Each jedes Element durchgehen ps.each(function(item) { alert(item.innerHTML); }); // Oder eine bestehende Funktion darauf ausführen ps.each(Element.hide);
  • 56. Prototype: Array Funktionen Prüfen ob alle Elemente einem Wert entsprechen // -> true (Ein leeres Array hat keine falschen Werte) [].all(); // -> true (Alle Werte in 1 bis 5 sind true) $R(1, 5).all(); // -> false (0 gilt als false) [0, 1, 2].all(); // -> false (Auf 9 kommt false zurück) [9, 10, 15].all(function(n) { return n >= 10; }); // Selbe Funktion mit "any", gibt jedoch schon bei // einem gültigen Wert true zurück
  • 57. Prototype: Array Funktionen Funktionsauswertung aller Elemente als Array // Gibt folgendes Array ['H', 'H', 'G'] ['Hitch', "Hiker's", 'Guide'].collect(function(s) { return(s.charAt(0).toUpperCase()); }); // Gibt alle Quadratzahlen von 1 bis 5 [1, 4, 9, 16, 25] $R(1,5).collect(function(n) { return(n * n); });
  • 58. Prototype: Array Funktionen Geprüfte Werte zurück bekommen // Wir wenden auf jedes Objekt Object.IsString an // Alle Werte die "true" ergeben kommen als Array zurück [1, 'two', 3, 'four', 5].filter(Object.isString); // Resultiert daher in ['two','four'] // Wir wenden auf jedes Objekt Object.IsString an // Alle Werte die "false" ergeben kommen als Array zurück [1, 'two', 3, 'four', 5].reject(Object.isString); // Resultiert daher in [1,2,3] // Das geht auch mit eigenen Funktionen [1, 'two', 3, 'four', 5].filter(function(item)) { // Hier item prüfen und true/false zurückgeben });
  • 59. Prototype: Array Funktionen Das selbe noch mit Regex // Alle Strings mit Doppelbuchstaben finden ['hello', 'world', 'this', 'is', 'cool'].grep(/(.)1/); // Ergibt folgendes Array: ['hello', 'cool'] // Innerhalb 1 bis 30 alle Zahlen die mit 0 oder 5 // enden holen und eins davon abziehen $R(1, 30).grep(/[05]$/, function(n) { return(n - 1); }); // Ergibt folgendes Array: [4, 9, 14, 19, 24, 29]
  • 60. Prototype: Array Funktionen Zahl, String oder Objekt in einem Array finden // Gibt true, da 10 im Range 1 bis 15 vorkommt $R(1, 15).include(10); // Gibt false, da Gross-/Kleinschreibung beachtet wird ['hello', 'world'].include('HELLO'); // Gibt true, da hello 1:1 so vorkommt ['hello', 'world'].include('hello'); // Gibt true, da 3 == '3' in JS true ergibt [1, 2, '3', '4', '5'].include(3);
  • 61. Prototype: Array Funktionen Objektmethoden aufrufen // Einfacher Aufruf, der Arraywert ist immer der 1. Parameter // Resultat ergibt: ['HELLO', 'WORLD'] ['hello', 'world'].invoke('toUpperCase'); // Parameter folgen dem Methodennamen // Substring calls ergeben: ['hel', 'wor'] ['hello', 'world'].invoke('substring', 0, 3); // Stoppt den 'change' event auf allen Input Feldern $$('input').invoke('stopObserving', 'change');
  • 62. Prototype: Array Funktionen Objektmethoden aufrufen (An eigenen Objekten) var AddCalc = Class.create({ initialize : function(first,second) { this.First = first; this.Second = second; }, Compute : function() { return(this.First + this.Second); } }); [ new AddCalc(5,5), new AddCalc(8,9)].invoke('Compute'); // Ergibt folgendes Array [10, 17]
  • 63. Prototype: Array Funktionen Feldwerte lesen und als Array zurückbekommen // Stringlänge aller Objekte herausfinden // Gibt folgendes Array: [5, 5, 4, 2, 4] ['hello', 'world', 'this', 'is', 'nice'].pluck('length'); // checked Feld aller Checkboxen lesen var checks = $$('input[type=checkbox]'); var values = checks.pluck('checked') // Alles umkehren for (i = 0;i < checks.length;i++) { checks[i].checked = !values[i]; }
  • 64. Prototype: Array Funktionen Array Sortieren // Nach Stringlänge sortieren // Ergibt: ['is', 'nice', 'this', 'world', 'hello'] ['hello', 'world', 'this', 'is', 'nice'].sortBy(function(s) { return(s.length); }); // Objekte mit internem Sortierwert sortieren MyObjectArray.sortBy(function(s) { // Mit „this“ könnte man hier auf das ganze Array zugreifen return(s.GetInternalOrder()); });
  • 65. Prototype: Array Funktionen Zusammenführen von Arrays var firstNames = ['Jane', 'Nitin']; var lastNames = ['Doe', 'Patel']; var ages = [23, 41]; // Ergibt: [['Jane', 'Doe'], ['Nitin', 'Patel']] firstNames.zip(lastNames); // Ergibt [['Jane', 'Doe', 23], ['Nitin', 'Patel', 41]] firstNames.zip(lastNames, ages); // Oder wir wenden eine Funktion an, um das // resultierende Array zu beeinflussen // Ergibt: ['Jane Doe is 23', 'Nitin Patel is 41'] firstNames.zip(lastNames, ages, function(tuple) { return(tuple[0] + ' ' + tuple[1] + ' is ' + tuple[2]); }); // Man kann so z.B. Objekte aus Arrays kreieren
  • 66. Prototype: $H / Hash Was ist ein Hash? Äquivalent zu „Dictionary“ in ASP oder .NET Zusammenfassen von Daten Kann als alternative zu Objekten verwendet werden. Ein Hash Hat zudem einige Hilfreiche Funktionen Methoden des Hash toQueryString(): Falls Post nicht möglich, Daten als Querystring toJSON()/toObject(): Liefern beide ein Objekt für z.B. Ajax Posts set()/get()/unset(): Kommen gleich im Codebeispiel update(): Erweitert den Hash mit dem übergebenen Objekt keys()/values(): Liefert entsprechende Arrays
  • 67. Prototype: $H / Hash Anwendung des Hash var h = $H({name: 'Michael', age: 21, country: 'England'}); // Ist das selbe wie... var h = new Hash({name: 'Michael', age: 21, country: 'England'}); // Mit "get" erhält man den entsprechenden Wert var country = h.get('country'); // Mit "set" kann man einen neue Wert setzen oder bearbeiten h.set('name','John'); h.set('lastname','Doe'); // Iterieren kann man auch hier mit der "each" Methode h.each(function(pair,index) { alert('on ' + index + ': ' + pair.key + '=' + pair.value); });
  • 68. Prototype: $R / ObjectRange Was ist ein ObjectRange? Ein Objekt, welches einen Range (Array) kreiert Wozu kann man es verwenden? Man weiss es nicht. z.B. um ein Zahle-n oder Buchstabenarray zu erzeugen, welches man dann irgendwie weiter verwenden kann Was kann der Range Als erstes: Alles was eine Enumeration auch kann include(): Überschreibt include() der Enumeration end/start: Properties für das beginnende und endende Objekt
  • 69. Prototype: $R / ObjectRange Anwendung des Range // Range von 1 - 10 $R(0, 10) // Range von String aa bis ah: aa ab ac ad af ag ah $R('aa', 'ah') // Range von 1 bis 10 ohne letzte Zahl (Also 1 bis 9) $R(0, 10, true).include(10) // Range gibt eine Enumeration, man kann also each verwenden $R(0, 10, true).each(function(value) { alert(value); });
  • 70. Prototype: $R / ObjectRange Anwendung des Range mit eigenem Objekt var BigCounter = Class.create({ initialize : function(value) { this.Value = value }, succ : function() { return(this.Value + 750); } }); // Range mit BigCountern: 1500, 2250 ... 6000, 6750 $R(new BigCounter(1500),new BigCounter(6750));
  • 71. Prototype: Funktionserweiterungen Methoden für Funktionen Prototype erweitert die Funktionsreferenzen automatisch Hier kommt Magie zum Einsatz Das gibt‘s sonst nirgendwo: Deferier- und delaybare Aufrufe, Parametererweiterungen und Methodisierung
  • 72. Prototype: Funktionserweiterungen Parameternamen herausfinden // Funktion. (Das alles geht auch mit Objektmethoden) function add(first, second) { return(first + second); } // Array der Argumente holen: ['first', 'second'] add.argumentNames();
  • 73. Prototype: Funktionserweiterungen Kontext binden (Wichtig für OOP implementationen) var AlertOnClick = Class.create({ initialize: function(msg) { this.msg = msg; // Klappt nicht, da Events „kontextlos“ sind $('submit').observe('click', this.Click); // Klappt, da der Objektkontext übergeben wird $('submit').observe('click', this.Click.bind(this)); }, Click: function(event) { event.stop(); $('message').update(this.msg).show(); } });
  • 74. Prototype: Funktionserweiterungen Parametererweiterung (Do it the indian way) function showArgs() { // 'arguments' ist ein Array aller Paremter alert($A(arguments).join(', ')); } // Liste der Parameter ausgeben: '1, 2, 3' showArgs(1,2,3); // Mit Curry eine Funktionskopie erstellen, welche // Die Funktion mit Default 1,2,3 aufruft var showExtended = showArgs.curry(1,2,3); // Diese mit weitere Parametern aufrufen: '1, 2, 3, a, b' showExtended('a','b');
  • 75. Prototype: Funktionserweiterungen Deferieren (Verschieben ans Ende) // Funktionen die mit "defer" aufgerufen werden, wird der // Interpreter erst Ausführen wenn er nichts mehr zu tun hat function showMsg(msg) { alert(msg); } showMsg("One"); // Normaler Aufruf showMsg.defer("Two"); // Verschobener Aufruf showMsg("Three"); // Normaler Aufruf // Output: One, Three, Two
  • 76. Prototype: Funktionserweiterungen Klassisches Beispiel (defer Methode) // Klassiker, den man immer wieder sieht: var Assistant = Class.create({ function : initialize() {}, // Funktion die ein Control per Effekt einblendet function : ShowInput(ele) { $(ele).appear({ duration: 3.0 }); // 1. Nicht im Objekt Kontext, 2. Unschön setTimeout('MyObject.DoSomething()',3000); }, // Funktion die nach dem Effekt aufgerufen werden soll function : DoSomething() {} });
  • 77. Prototype: Funktionserweiterungen Klassisches Beispiel (defer Methode) var Assistant = Class.create({ function : initialize() {}, // Funktion die ein Control per Effekt einblendet function : ShowInput(ele) { $(ele).appear({ duration: 3.0 }); // 1. Im Objektkontext, 2. Optimal, da am Funktionsende. // Wird ausgeführt wenn der Interpreter idle ist, und das // ist er zufälligerweise erst, wenn der Effekt beendet ist this.DoSomething.defer(); }, // Funktion die nach dem Effekt aufgerufen werden soll function : DoSomething() {} });
  • 78. Prototype: Funktionserweiterungen Delayen (Verschieben auf fixen Zeitpunkt) // Ist defer nicht sicher genug, geht es immer noch so var Assistant = Class.create({ function : initialize() {}, // Funktion die ein Control per Effekt einblendet function : ShowInput(ele) { $(ele).appear({ duration: 3.0 }); // Funktonsaufruf gleich wie Effekt delayen this.DoSomething.delay(3.0); }, // Funktion die nach dem Effekt aufgerufen werden soll function : DoSomething() {} });
  • 79. Prototype: Funktionserweiterungen Delayen mit Parameter var Assistant = Class.create({ function : initialize() {}, // Funktion die ein Control per Effekt einblendet function : ShowInput(ele) { $(ele).appear({ duration: 3.0 }); // Erst das Timeout, dann die Parameter this.DoSomething.delay(3.0, 'hello', 'world'); }, // Funktion die nach dem Effekt aufgerufen werden soll function : DoSomething(param1, param2) {} });
  • 80. Prototype: Funktionserweiterungen Methodisierung (Statische Funktionen an Objekte binden) // Funktion, die auf ein Objekt, das "name" Prop. setzt function setName(target, name) { target.name = name; } // Kann man z.B. so ohne Kontext verwenden object = {}; setName(object, 'Fred'); // Man kann aber auch das Objekt "Methodisieren" obj.setName = setName.methodize(); // "target" ist nun "this" und wird direkt angewendet obj.setName('Barney'); // Prototype setzt dies für fast alle Funktionen ein
  • 81. Prototype: Funktionserweiterungen Bestehende Methoden erweitern // capitalize Funktion mit einem Parameter erweitern String.prototype.capitalize = String.prototype.capitalize.wrap( function(OriginalMethod, eachWord) { if (eachWord && this.include(" ")) { // Wenn Parameter (true), jedes Wort kapitalisieren return(this.split(" ").invoke("capitalize").join(" ")); } else { // Oder die bisherige Standarmethode anwenden return(OriginalMethod()); } } ); "hello world".capitalize(); // "Hello world" "hello world".capitalize(true); // "Hello World"
  • 82. Prototype: Number Methoden Erweiterung von „Math“ Number vereint Math und mehr Beispiele - Fügt für jede Zahl abs(), ceil, floor(), und round() hinzu - toColorPart(): Gibt die Hex Version einer Zahl zurück - toPaddedString(n): Gibt den Zahlenwert mit führenden Nullen zurück
  • 83. Prototype: The Object Object Wer profitiert davon Alle primitiven Datentypen, alle Objekte, selbst Eigenbauten Hilfreiche Funktionen - clone(): Erzeugt eine Shallow Copy. Deep Copy umsetzbar - extend(): Erweitert ein bestehendes Objekt - inspect(): Gibt Debug-Informationen des Objekts aus - Anwendbar statisch oder im Objektkontext als Methode Validierung Validierung (Nur statisch) kann nicht schaden: isArray(), isElement(), isFunction(), isHash(), isNumber(), isString(), isUndefined().
  • 84. Prototype: PeriodicalExecuter Warum nicht setInterval? Weil die Ausführungszeit dort nicht eingerechnet ist Und sonst? - Die stop() Methode haltet den Executer an - Geeigneter für OOP da Kontextübergabe möglich
  • 85. Prototype: PeriodicalExecuter Simpler Aufruf // Übergabe einer direkten Funktion new PeriodicalExecuter(function(executer) { if (!confirm('Hey bananas, what'cha doin'?')) { executer.stop(); } }, 5.0); // Verwendung innerhalb eines Objekts this.Exec = new PeriodicalExecuter(this.DoIt.bind(this),5.0); // Funktion DoIt als Beispiel DoIt : function(pe) { pe.stop(); // Übergebenen Executer stoppen this.Exec.stop(); // Oder die Objektreferenz, da Kontext }
  • 86. Prototype: Prototype.Browser Der Prototype Namespace Bietet nicht viel gescheites ausser „Browser“ Ein Set von Booleans Wenns mal doch nicht klappt: Prototype.Browser .IE: Check ob IE vorhanden (Zudem: IE6, IE7, IE8) .Opera: Check auf jegliche Versionen von Opera .WebKit: Check auf Webkit Browser (Safari, Anroid) .MobileSafari: Expliziter Check auf iPhone Browser .Gecko: Browser basierend auf Gecko (Firefox, Netscape)
  • 87. Prototype: String Sind wir nicht endlich durch? Nein. Mit dem String Objekt kommt nochmal eine grobe Sache Gültigkeit der Methoden Jeder String besitzt die neuen Methoden, da Prototype direkt das String Objekt erweitert (Wie bei Zahlenwerten) Wichtige Funktionen .capitalize(): Ersten Buchstaben gross schreiben .endsWith()/startsWith(): Start oder Ende des Strings prüfen .(un)escapeHtml(): Konvertiert reinen Text in HTML Entitäten und zurück
  • 88. Prototype: String Noch etwas mehr Funktionen .evalJSON(): JSON String zu einem Objekt konvertieren .isJSON(): Gibt an, ob der String evaluierbares JSON enthält .evalScripts(): Javascript Code innerhalb des Strings ausführen .extractScripts(): Gibt ein Array aller Javascript Codezeilen zurück .sub()/.gsub(): Einfache Form von Regex und/oder Replace .scan(): Erlaubt die Anwendung eines Callback für jeden Teilstring .stripScripts(): Löscht alle <script> Tags und JS Codes aus dem String .stripTags(): Entfernt alle HTML Tags aus dem String .toArray(): Erstellt ein Char Array aus dem String .toQueryParams(): Erstellt JSON Code aus URL Parametern .truncate(): Kürzt den String auf X-Zeichen und fügt Suffix an
  • 89. Prototype: Template Sowas wie String.Format in .NET String mit Variablen durch Objektproperties ersetzen Gedacht für mehrfache Verwendung Das Template ist z.B. für Listenansichten sehr geeignet, lässt aber auch herkömmlichen „Verknüpfungscode“ schöner aussehen Wichtige Funktionen .evaluate(obj): Ersetzt die Templatevariablen mit entsprechenden Variablen im gegebenen Objekt (JSON oder Prototype Objekt)
  • 90. Prototype: PeriodicalExecuter Anwendung des Template var conv1 = { from: 'meters', to: 'feet', factor: 3.28 }; var conv2 = { from: 'kilojoules', to: 'BTUs', factor: 0.9478 }; var conv3 = { from: 'megabytes', to: 'gigabytes', factor: 1024 }; // Template erstellen var tpl = new Template( 'Multiply by #{factor} to convert from #{from} to #{to}.' ); // Alle formatieren... mit on-the-fly-array-each :D [conv1, conv2, conv3].each(function(conv){ tpl.evaluate(conv); }); // -> Multiply by 3.28 to convert from meters to feet. // -> Multiply by 0.9478 to convert from kilojoules to BTUs. // -> Multiply by 1024 to convert from megabytes to gigabytes.
  • 91. Inhalte Scriptaculous Effekte Effektbeispiele, Queues, Combination, Toggle Controls Slider, Sortable(s), Ghostly, Test.Unit Ajax Autocompleter, In Place Editing
  • 92. Scriptaculous: Effekte Zurück zum Kerngeschäft Scriptaculous bietet Effekte und Controls Warum bietet Prototype das nicht an? Prototype und Scriptaculous haben eine strikte Trennung aus funktionalem Framework und Effekten/Controls Effekttypen Es wird zwischen Kerneffekten und Kombinationseffekten unterschieden
  • 93. Scriptaculous: Effektbeispiele Anzeige-Effekte Effect.Highlight: Lässt die Hintergrundfarbe kurz aufblinken Effect.Morph: Erlaubt Farbwechsel zwischen zwei Farben Effect.Move: Absolute oder Relative Veränderung der Position Erschein-Effekte Effect.Appear: Sanftes Einblenden eines Controls Effect.BlindDown: Herunterfahren eines Controls Ausblende-Effekte Effect.Fade: Sanftes ausblenden eines Controls Effect.BlindUp: Herauffahren eines Controls
  • 94. Scriptaculous: Effekt Queues Effect.Queue Jeder Effekt lässt sich in eine Queue stellen, da er ansonsten parallel mit anderen Effekten ausgeführt würde Einschränkung Man muss eindeutige „Scopes“ definieren, um Sie während der Laufzeit mit Effect.Queue steuern (z.B. Abbrechen) zu können Beispiel Das folgende Beispiel zeigt die Grundlegende Arbeit mit Queues. Merke: Queues sind nur nötig, wenn Effekte auf dem selben Element nacheinander anstatt gleichzeitig ausgeführt werden sollen
  • 95. Scriptaculous: Effekt Queues Erstellen von Queues // Menu anzeigen, ans Ende des 'sc_menu' Scope new Effect.SlideDown('menu', { queue: { position: 'end', scope: 'sc_menu' } } ); // Banner anzeigen, ans Ende des 'sc_banner' Scope new Effect.Appear('bannerbig', { queue: { position: 'end', scope: 'sc_banner' } } ); // Menu pulsieren lassen, nach SlideDown Effekt new Effect.Pulsate('menu', { queue: { position: 'end', scope: 'sc_menu' } } );
  • 96. Scriptaculous: Effekt Queues Steuern der Scopes // z.B. die Menu Queue holen var queue = Effect.Queues.get('sc_menu'); // 'queue' ist eine Prototype Enumeration, daher... queue.each(function(effect) { effect.cancel(); }); // ... um alles abzubrechen oder ... queue.invoke('cancel'); // …Wartezeit zwischen Effekten beeinflussen queue.interval = 100;
  • 97. Scriptaculous: Combination / Toggle Combinations toggeln und mergeln SlideUp()/Down(), Appear()/Fade() und BlindDown()/Up() lassen sich mit toggle() einfach kombinieren bzw. ein- und ausblenden Sinn dahinter Spart einiges an Code, da ein-/ausblenden mit einer Zeile Code realisiert werden kann