Runden mit JavaScript

Heute musste ich mich mal wieder etwas mit JavaScript herumschlagen. Dabei musste ich das Ergebnis einer Rechnung auf zwei Stellen runden. Nur wie geht das? Mit Math.round() wird eine Dezimalzahl ohne jegliche Kommastellen zurückgegeben. Mit einem kleinen Workaround konnte ich das Problem lösen, aber etwas unschön ist es schon. Gibts da keine bessere Lösung?
var wert1=100;
var wert2=3;

ergebnis=Math.round(wert1/wert2);              // gibt 33

ergebnis=Math.round((wert1/wert2)*100)/100;    // gibt 33.33

Formular für Routenberechnung mit Google Maps

Bei gewissen Homepages kann es von Vorteil sein, wenn man dem Benutzer die Möglichkeit bietet die Route zu einem bestimmten Ort anzuzeigen. Etwa den Weg vom Benutzer zu Hause zum Geschäft. Dazu eignet sich Google Maps hervorragend.
Um die Routenberechnung für den Benutzer etwas einfacher zu machen, kann man auf der eigenen Homepage ein Formular anbietet, wo er nur die eigene Adresse eingeben muss und in einem neuen Fenster wird dann die Route angezeigt.
Das ganze ist recht simpel und am Beispiel von Veloplus in Wetzikon sieht das zum Beispiel so aus:
<form action="http://google.ch/maps" method="get" target="_blank">
<input type="hidden" name="daddr" value="Rapperswilerstrasse 22, 8620 Wetzikon ZH (V Plus AG)" />
Abfahrtsort: <input type="text" name="saddr" />
<input type="submit" value="Los!" />
</form>

Mehrere Checkboxen mit Javascript markieren

Manchmal möchte man auf einer Webseite den Benutzen die Möglichkeit geben, mehrere Checkboxen aufs mal zu Markieren. So muss der Benutzer nicht jede Checkbox einzeln anklicken, sondern kann mit einem klick auf "Alle Markieren" alle Checkboxen markieren.

Dies ist keine grosse Sache. Mit einer JavaScript Funktion kann man das Problem recht simpel lösen. Über einen Link wird die Funktion aufgerufen, welche dann die Checkboxen markiert. Also mal angenommen, wir haben den folgenden HTML Code:
<input type="checkbox" name="box" value="1" />
<input type="checkbox" name="box" value="2" />
<input type="checkbox" name="box" value="3" />
<input type="checkbox" name="box" value="4" />
<input type="checkbox" name="box" value="5" />
<input type="checkbox" name="box" value="6" />
<input type="checkbox" name="box" value="7" />
<input type="checkbox" name="box" value="8" />
<input type="checkbox" name="box" value="9" />

Nun benötigen wir im Header der HTML Datei noch die folgende Javascript Funktion:
var marker=false;
function mark()
{
    var elements=document.getElementsByName("box");

    if(marker==false)
    {
        for(i=0;i<elements.length;i++)
        {
            elements[i].checked=true;
            marker=true;
        }
    }
    else
    {
        for(i=0;i<elements.length;i++)
        {
            elements[i].checked=false;
            marker=false;
        }
    }
}

Wenn diese Funktion nun aufgerufen wird, werden beim ersten mal alle Checkboxen markiert, beim zweiten Durchgang wird die Markierung wieder entfernt. Der Zustand der Markierung wird in der Variable marker gespeichert.

Aufrufen kann man die Funktion mit einem Link in der folgenden Art. Allerdings gibt es da auch noch viele andere Möglichkeiten.
<a href="#" onClick="mark()">Alle Markieren</a>

Webseite in verschiedenen Browsern testen

Über Falki bin ich wieder auf den Dienst Browsershots gestossen. Jeder, der schon mal eine Homepage erstellt hat kennt das Problem wohl. Man hat das Design fertig gestellt und schaut es dann in einem anderen Browser an. Und es sieht völlig anders aus.
Bei privaten Homepages ist das ja nicht so gravierend, aber Firmen Homepages sollten doch in jedem Browser gleich aussehen. Und valides (X)HTML und CSS garantiert ja auch nicht, dass die Homepage überall gleich aussieht (IE).
Nun kann man ja nicht jeden Browser auf dem Computer installiert haben und zudem gibt es ja auch noch Darstellungs-Unterschiede im Firefox unter Windows und Linux. Nicht zuletzt auch wegen den verschiedenen Schriftarten.

Browsershots ermöglicht es einem zu sehen, wie eine Homepage in verschiedenen Browsern aussieht. Einfach die URL eingeben und die gewünschten Browser auswählen. Alle momentan populären Browser stehe zur Verfügung. IE, Firefox, Opera, Safari und das auch unter Windows, Linux und Mac OS.
http://images.t-error.ch/blog/514/browsershots_uebersicht.jpg


Ich habe meine Seite natürlich auch getestet und bin wirklich zufrieden mit dem Ergebnis. Sogar im IE 6, der ja nicht gerade für seine CSS Kompatibilität bekannt ist, sieht die Seite sehr gut aus. Nicht zuletzt dank dem IE 6 CSS hack.
http://images.t-error.ch/blog/514/page_ie6_win2k.jpg


Der einzige Browser, in dem es überhaupt nicht gut aussieht ist der IE 5. Allerdings mache ich da keine grossen Aufwände mehr, damit die Seite auch dort gut aussieht. Sehr viele Benutzer sind mit dem IE 5 ja nicht mehr unterwegs.
http://images.t-error.ch/blog/514/page_ie5_win2k.jpg
Man achte auf die Navigation

DIV Container mit CSS im IE 6 zentrieren. Die Lösung

Vor zwei Wochen habe ich mich ja bereits darüber beklagt, dass man im Internet Explorer 6 Div Container nicht vernünftig mit CSS ausrichten kann. margin-left:auto;margin-right:auto;, die eigentlich korrekte Lösung wird einfach Ignoriert.
Dank einem Kommentar von Evert aus Holland (den ich dummerweise im Zuge einer Spamsäuberungsaktion gelöscht habe, sorry) kenne ich nun eine gute Lösung. Sie ist eigentlich sehr simpel. Man erstellt einen DIV Container um alles herum und zentriert den Inhalt. Da das aber nur im IE 6 so ist, darf das CSS-File dazu auch nur im IE 6 geladen werden. Glücklicherweise gibt es da Kommentare, die als Browserweichen funktionieren.

Nun aber von vorne. Ich erstelle einen neuen DIV-Container (fett) um mein bestehendes Design herum.
<div id="container">
<div id="main">
    <div id="navLeft">
        Navigation
    </div>
    <div id="content">
        inhalt
    </div>
</div>
</div>

Nun muss das CSS-File im IE 6 geladen werden. Wie gesagt, fungieren hier die Kommentare als Browserweiche.
<!--[if IE 6]>
<link href="ie.css" rel="stylesheet" type="text/css" media="screen" />
<![endif]-->

Und zum Schluss noch der Inhalt der CSS-Datei. Für den Container #main muss man die Ausrichtung wieder zurücksetzten, da sonst der ganze Text zentriert ist.
#container {
    text-align: center;
    }

#main {
    text-align:left;
    }


Thank you Evert for this comment and sorry for deleting it. It was a mistake.

Überlange Codezeilen kürzen

Und wieder mal etwas von der HTML/CSS Front. Und zwar habe ich beim erstellen des neuen Designs mit der festen Breite bemerkt, dass gewisse Texte (hauptsächlich Code) zu lang für das Design ist. Sprich, der Code ragt zu weit nach rechts.
Hier ein Beispiel von diesem Artikel.
http://images.t-error.ch/blog/487/div_overflow_standard.jpg


Eine Möglichkeit um das Problem zu lösen wäre das Umbrechen des Textes nach einer bestimmen Anzahl von Buchstaben. Bei einer Schriftart mit einer festen Breite wie Courier würde das auch recht gut funktionieren. Nur macht das den Code völlig unleserlich, wenn da einfach irgendwo umgebrochen wird.
Es muss also eine andere Lösung her. Das CSS Element Overflow bietet sich da an. Mit der Angabe scroll kann man definieren, dass es um das Div Element Scrollbalken hat. Dadurch ist das Element nicht breiter als es sollte. Nur haben so auch Div Element die nicht zu breit sind Scrollbalken und das sieht wiederum schlecht aus.
Mit overflow:auto; kann man dem Browser die Wahl überlassen. Und hier scheinen sich die meisten Browser mal mehr oder weniger einig zu sein. Div Elemente die nicht zu breit sind habe keine Scrollbalken, diejenigen die zu breit sind haben aber Scrollbalken:
http://images.t-error.ch/blog/487/div_overflow_auto.jpg


Dies funktioniert im Firefox, Opera und im IE 6 & 7. Andere Browser habe ich nicht getestet. Der einzige Unterschied ist, dass der IE auch vertikale Scrollbalken anzeigt, obwohl diese nicht nötigt wären. Firefox und Opera verzichten darauf, wie es sich gehört.

DIV Container mit CSS im IE 6 zentrieren

Wie schonmal erwähnt arbeite ich momentan an einem neues Design für die Homepage. Das Grunddesign steht momentan und ich bin auch wirklich damit zufrieden. Und auf etwas bin ich besonders stolz. Die Seite sieht im Firefox und Opera unter Linux und Windows genau gleich aus. Eigentlich keine grosse Kunst, aber das besonders schöne: Auch im Internet Explorer 7 wird die Seite korrekt angezeigt. Der Grund warum ich IE 7 und nicht einfach IE schreibe, ist eigentlich der Grund warum ich diesen Beitrag schreibe. Im IE 6 sieht es nicht mehr so rosig aus. Die Seite sollte eigentlich zentriert sein, aber im IE 6 klebt sie schön am linken Rand. IE 6 und CSS verträgt sich leider nicht so gut.

Die neue Seite ist ähnlich aufgebaut, wie die jetzige. Oben ein Header, danach das Menu und dann auf der linken Seite eine Navigation und rechts daneben der Inhalt. Aufs gröbste gekürzt sieht der Code so aus:
<div id="main">
    <div id="navLeft">
        Navigation
    </div>
    <div id="content">
        inhalt
    </div>
</div>

Nur mit HTML kommt man da natürlich nicht so weit, also braucht man auch noch etwas CSS Code:
#main {
    width:                   745px;
    margin-top:              5px;
    margin-bottom:           0px;
    margin-left:             auto;
    margin-right:            auto;
    }

#navLeft {
    margin-left:             0px;
    width:                   160px;
    float:                   left;
    }

#content {
    margin-left:             165px;
    width:                   580px;
    }

Grundsätzlich ist es derselbe Code wie bei dieser Seite, nur hat der Container #main eine feste Breite und ist zentriert, oder sollte es zumindest sein. Wie gesagt funktioniert dieser Code im Firefox, Opera und IE7 wunderbar, nur im IE 6 ist die Seite nicht zentriert. Der Container wird ja mit den Elementen margin-left:auto; und margin-right:auto; zentriert. Nur scheint das im IE 6 nicht zu funktionieren.
Kennt da jemand eine andere, funktionierende Lösung? Idealerweise XHML und CSS valide?

Dynamische oder feste Breite?

Das Thema habe ich vor längerer Zeit schon mal angesprochen. Allerdings habe ich mich damals über die Designs mit einer festen Breite geärgert. Ich habe in letzter Zeit vermehrt darauf geachtet, welche Designs nun Benutzerfreundlicher sind. Schlussendlich ist das ganze sicher immer noch eine Ansichtssache, aber ich finde, dass man Text besser lesen kann, wenn er sich nicht über die ganze Seite erstreckt. Also bei einem Design mit einer festen Breite. Dies setzt aber voraus, dass der Text auch sauber strukturiert ist und Absätze hat. Sonst verliert man sich schnell in einem Textblock.
Nun bin ich mir am überlegen, ob ich mein Design umstellen soll. Von der dynamischen zur festen Breite.
Ich habe bereits einen kleinen Test gemacht und das sieht nicht schlecht aus. Nur mit Codeschnippseln gibt es Probleme, da diese nicht umgebrochen werden. Bei den Bildern habe ich mich sowieso an eine maximale Breite von 555 Pixeln gehalten. Von daher sollte es keine Probleme geben.
Allerdings würde ich gerne noch einige Meinungen von Lesern dazu hören. Ich denke die regelmässigen Leser benutzen sowieso einen Feedreader und der Feed ist davon ja nicht betroffen. Aber ich würde mich über Feedback von Lesern freuen, die ab und zu mal wieder hier vorbeisurfen.

Für Leute die das Thema sonst noch interessiert gibt es auf dem Beast Blog einen interessanten Artikel (en)

Bilder mit JavaScript preloaden

Ich versuche momentan eine kleine und simple Galerie zu Programmieren. Ein PHP Script soll die Bilder aus eine Verzeichnis auslesen und dann mit Lightbox anzeigen. Der Nachteil von Lightbox ist aber, dass es erst funktioniert, wenn die Seite komplett geladen ist. Und wenn es da mehrere Bilder gibt, kann das Laden der Seite auch mal länger dauern und die wenigsten Besucher wollen da warten.
Ich versuche diese Problematik nun mit einem Preloader zu umgehen. Bisher ohne grossen Erfolg. Aber immerhin weiss ich jetzt, wie man Bilder mit JavaScript "preloadet."
<script language="JavaScript" type="text/javascript">
    <!--
        if (document.images)
        {
            preload_obj=new Image();
            preload_obj.src="images/test.jpg";
        }
    //-->
</script>

Recht simpel. Es wird ein neues Objekt erstellt und danach mit src die Quelle der Datei zugewiesen. Natürlich kann man so mit PHP auch mehrere Bilder preloaden.

JavaScript Effekte mit Scriptaculous

Ich bin gerade etwas mit den Scriptaculous Libraries am Pröbeln. Eine sehr nette, und einfache Sache. Einige Teile sind sicher etwas Eyecandy, aber das kommt je länger desto mehr. Auch im Webbereich.
Mit Scriptaculous kann man "Aufklappeffekte" wie ich sie bei meiner Tourenverwaltung habe, ganz einfach und noch etwas schöner realisieren. Dazu benötigt man nur die neusten Scriptaculous (blödes Wort) Libraries. Dieso kopiert man zusammen mit der Datei prototype.js in einen Ordner. Vorzugsweise javascript/. Wie man erahnen kann, basiert Scriptaculous auf Prototype, allerdings muss Prototype nicht zusätzlich heruntergeladen werden.
Nun müssen die Libraries noch in die Seite eingebunden werden. Dies funktioniert wie bei jedem JavaScript. Bei Scriptaculous kann noch angegeben werden, welche Module geladen werden sollen. Dies macht man mit dem load Parameter. Wenn dieser Parameter nicht angegeben wird, werden alle Module geladen. Ich benötige aber nur das Effects Modul also lade ich auch nur dieses.
<script type="text/javascript" language="JavaScript" src="js/prototype.js"></script>
<script type="text/javascript" language="JavaScript" src="js/scriptaculous.js?load=effects"></script>
Auf der Scriptaculous Homepage hat es schon diverse Beispiele zu den verschiedenen Effekten. Mich interessierte der Effekt toggle mehr, da es damit möglich ist, ein Element auf und zu zu klappen. Mit einem Klick auf ein Element kann so ein anderes Element geöffnet oder geschlossen werden. Hier ein simples Codebeispiel.
<div onClick="new Effect.toggle($('element'),'blind')">click</div>
<div id="element"><div>test test test</div></div>
Damit kann man mit einem Click das Element element öffnen und wieder schliessen. Hier wird der Effekt blind verwendet. Wichtig ist, dass im zu öffnenden Element noch ein zusätzlicher Divcontaoiner ist, sonst funktionieren einige Effekte nicht korrekt. Das Beispiel sieht mit etwas zusätzlichem CSS dan so aus:
blind
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test

Oft möchte man es ja so haben, dass das Element von Anfang an geschlossen ist. Dazu kann man ganz einfach das CSS Element display mit dem Wert none benutzen. Das sieht dann so aus.
blind

Zusätzlich gibt es noch die Effekte slide und appear welche mich persönlich nicht so ansprechen. Mit gefällt blind am besten. Zum Schluss aber noch je ein Beipsiel.
slide

appear

Achtung: Lightbox2 verwendet schon Scriptaculous und Prototype. So muss man diese Libraries nicht mehr laden.