Kriterien für “gutes” Javascript
• Aus Benutzersicht:
– macht die Page-Handhabung leichter
– sofort/immer benutzbar (blockt nicht)
– ist Barrierefrei
– bereichert die Webseite
– “stört nicht”
– ist nicht zum Selbstzweck
– beschleunigt Abläufe
– in meiner Sprache
Gut Wartbar
• Wie schreibst Du Javascript?
– jQuery, YUI und Konsorten?
– alles von Hand?
Gut Wartbar
• Du verwendest und verstehst nur ein
Javascript Framework?
– Du solltest Javascript lernen!
– Verstehe was hinter den Kulissen
passiert!
– Lerne Fehlermeldungen zu verstehen!
– Viele Fehler werden offensichtlich
Gut Wartbar
• Du verwendest aus Prinzip keine
Javascript Frameworks?
– Du solltest!
Gut Wartbar
• Javascript Frameworks/Libraries
helfen
– nicht immer das Rad neu zu erfinden
– Code aktuell zu halten
– Qualität zu sichern
– Modulare Applikationen zu entwerfen
anstatt Scripts zu schreiben
Gut Wartbar
• “Standing on the Shoulders of
Giants”
• “Zwerge auf den Schultern von
Riesen”
• “nanos gigantium humeris
insidentes”
Wiederverwendbar
• finde patterns
• “grösste” gemeinsame Nenner
• wenn Du jeden Monat ein neues
Dropdown Menü schreibst ist etwas
sehr falsch
• schreibe EIN Dropdown Menü und
entwickele es weiter
• mit einheitlichen Schnittstellen
Wiederverwendbar
• Open Source != “ich gebe meine
kostbaren Ideen umsonst weg”
• Open Source == “ich kriege
kostenlose Tester, Entwickler,
Ruhm und Ehre!”
• github ist voll mit großartigem Code
• “FORK OFF” - mach es besser!
• Ein Plugin für eine Library ist ein
super start!
Erweiterbar
•Was ist das populärste an jQuery?
- DIE PLUGINS!
$.fn.extend({
accessibleTabs: function(config) {
return this.each(function() {
//...
}
}
});
$(".tabs").accessibleTabs();
Erweiterbar
• Jedes Modul kann plugins haben!
• Formular Validierung
addValidator : function(name,func){
this.validators[name] = func;
}
this.addValidator('isText',function(el){
var filter = /^[a-zA-Z ]+$/;
return filter.test(el.get('value'));
});
if( !this.validators['isText'](el) ){ //error!}
Dokumentiert
• Dokumentation schreiben macht
nicht Spass
• Code lesen den man vor 5 Jahren
geschrieben und nicht dokumentiert
hat noch weniger...
• Undokumentierten Code lesen den
andere geschrieben haben am
allerwenigsten...
Dokumentiert
• Klare Variablen und
Funktionsnamen nutzen:
– a = b(c) // Hä?
– user = getUserOfProduct(productId) // Ah!
• Gute Kommentare
– // IE seems to break here...
– // dirty hack. This must never go live!
– // this works. No idea why. Better don’t touch.
Dokumentiert
• YUI Doc jetzt noch schöner
dank Carlo & Dana:
http://www.yuiblog.com/blog/
2010/10/01/yuidoc-dana-theme/
Optimiert
• Guter Development Code != guter
Production Code
• Gut für Development:
– Code granular auf viele Dateien Verteilt
• Modul / config / i18n / init / etc
– Viele Kommentare
– Beispiele
Optimiert
• Guter Development Code != guter
Production Code
• Gut für Production:
– Code kombiniert in wenige bis eine
Datei
– Kommentare & Whitespace weg
– optionale Code-Minification
Sicher
• XSS ist das grösste
Sicherheitsproblem
• Keine User Eingaben direkt wieder
ausgeben
• Eingaben filtern!
whitelisting nicht blacklisting
• Datentypen definieren
• traue nichts und niemanden
• Sei Paranoid...
Sicher
• Caja
http://en.wikipedia.org/wiki/
Caja_project
• “virtuelle iFrames”
• keine direkten Zugriffe auf native
Objekte
• Übersetzer auf dem Server
• YUI3 erste Javascript Library die
kompatibel ist
Performant
• Caching von DOM-Zugriffen
var el = document.getElementById('bla');
• CSS ist viel schneller als Javascript
wenn es darum geht den DOM zu
ändern
el.addClass('bla');
statt
el.css({
width:'20px',
height:'20px',
...
});
Performant
• “reflows” vermeiden
Bei jeder DOM-Manipulation muss
der Browser neu rendern!
• Bei Style Änderung von grossen
Mengen von Elementen ist CSS
Modifikation sogar noch schneller!
$('<style type="text/css"> a { color: red; } </
style>').appendTo('head');
Performant
• DOM ändern mit:
– klassischen DOM Methoden:
el = document.getElementById('list');
l1 = document.createElement('li');
t1 = document.createTextNode('hallo 1');
l2 = document.createElement('li');
t2 = document.createTextNode('hallo 2');
l3 = document.createElement('li');
t3 = document.createTextNode('hallo 3');
l1.appendChild(t1);
l2.appendChild(t2);
l3.appendChild(t3);
el.appendChild(t1).appendChild(t2).appendChild(t3);
Performant
• DOM ändern mit:
– innerHTML:
el = document.getElementById('list');
li = '<li>hallo 1</li>';
li += '<li>hallo 2</li>';
li += '<li>hallo 3</li>';
el.innerHTML = li;
– Schneller als DOM-Methoden (wegen IE)
Performant
• DOM ändern mit:
– innerHTML:
el = document.getElementById('list');
li = [];
li.push('<li>hallo 1</li>');
li.push('<li>hallo 2</li>');
li.push('<li>hallo 3</li>');
el.appendChild(li.join());
– noch schneller weil string
concatenation in IE langsam ist
Performant
• DOM ändern mit:
– innerHTML:
el = document.getElementById('list');
li = [];
li[0] = '<li>hallo 1</li>';
li[1] = '<li>hallo 2</li>';
li[2] = '<li>hallo 3</li>';
el.appendChild(li.join());
– noch schneller weil auch array.push in
IE langsam ist
Performant
• DOM ändern mit:
– DOM Fragment:
l = document.getElementById('list');
f = document.createDocumentFragment();
l1 = document.createElement('li');
t1 = document.createTextNode('hallo 1');
...
l1.appendChild(t1);
l2.appendChild(t2);
l3.appendChild(t3);
f.appendChild(l1).appendChild(l2).appendChild(l3);
el.appendChild(f);
– Noch schneller! Nur ein DOM-Zugriff!
Sauber getrennt
• CSS für Javascript
– <script>
document.documentElement.className += ' js';
</script>
– <style>
.module{
/* ohne JS */
}
.js .module{
/* mit JS */
}
</style>
Sauber getrennt
• HTML für Javascript
– Partials mit Mustache Templating
für Ajax content
– /partials/login_success.html
– Hallo {{user_name}}
Sie haben sich erfolgreich angemeldet.
Ihr Punkte Stand ist {{user_points}}
– {
user_name : “Spundekäs”,
user_points : 123
}
– http://mustache.github.com/
Optional
• Progressive Enhancement
– Basis Funktionalität der Webseite/
Webbapp muss gewährleistet sein auch
wenn der Useragent kein Javascript
spricht!
• Mobile != iPhone (Opera Mini ist No.1!)
• Suchmaschinen
• Paranoide Sysadmins
• Yahoo hat ~1% non-js User
• ...
Optional
• Basis Seite hat Interaktion dank:
– Links
– Formulare
– Alles wichtige ist sichtbar
• Mit Javascript:
– Links die die Seite ändern werden zu
Buttons
– Formulare werden direkt verarbeitet
– Info kann versteckt/gezeigt werden
International/Multilingual
• UTF-8
• RTL
• Wenn möglich Strings aus der
HTML-Seite übernehmen
• Übersetzungsstandards nutzen
– Text {0} mehr text {1} noch mehr text {2}
Text {0:currency} mehr text {1:symbol} noch
mehr text {2:amount} // {variable:comment}
International/Multilingual
• Variabler Satzbau = mehrstufige
Übersetzung
– T_WELCOME : {
en_US:”We welcome {0:user}”
de_DE:”Wir heissen {0:user} willkommen”
}
– getText(‘de_DE’,‘T_WELCOME’,{user:Schoppekopp})
• ISO Standards beachten
• HTML in Strings ist nicht ideal aber
besser als pseudo code
• bold macht Asia Schriften unlesbar
International/Multilingual
TRANSLATIONS = { // siehe http://internationalisationtips.com
! O: "{market} open",
! OT: "{market} open in {timePeriod}",
! OE: "{market} open early",
! OET: "{market} open early in {timePeriod}",
! OER: "{market} open early for {reason}",
! OERT: "{market} open early for {reason} in {timePeriod}",
! OL: "{market} open late",
! OLT: "{market} open late in {timePeriod}",
! OLR: "{market} open late for {reason}",
! OLRT: "{market} open late for {reason} in {timePeriod}",
! C: "{market} close",
! CT: "{market} close in {timePeriod}",
! CE: "{market} close early",
! CET: "{market} close early in {timePeriod}",
! CER: "{market} close early for {reason}",
! CERT: "{market} close early for {reason} in {timePeriod}",
! CL: "{market} close late",
! CLT: "{market} close late in {timePeriod}",
! CLR: "{market} close late for {reason}",
! CLRT: "{market} close late for {reason} in {timePeriod}",
! X: "{market} closed"
};
Barrierefrei
• Tab Reihenfolge ist entscheidend
• mit focus() kann der Nutzer geführt
werden
• tabindex=-1 macht alles
fokussierbar (für Javascript)
• Ajax funktioniert aber die Ladezeit
muss erklärt werden
• Virtual Buffer aktualisieren
Barrierefrei
• manche Effekte können die
Javascript Version verständlicher/
Barrierefreier machen als ohne
– highlight() // yellow fade zur
temporären Hervorhebung eines
geänderten Bereiches
– auf-/zuklappen // mit guter Animation
leichter verständlich als hart auf/zu
Barrierefrei
• WAI-ARIA
– bringt bekannte Desktop-
Bedienkonzepte barrierefrei in den
Browser
– Bringt unsemantischem Markup
Semantik bei
Barrierefrei
• WAI-ARIA
– echte realtime updates
• Live Regions
– echter Formular Validierungsstatus
• aria-required="true"
• aria-invalid="true"
– echte Dialoge
• role="alert"