Thomas: Hintergrundbilder

Hallo zusammen!

Ich kann im Forum, so wie im Archiv nichts dazu finden, also frag ich mal neu; weiß auch nicht, ob ich hier richtig bin...

Wie erreiche ich, dass ein Hintergrund meiner Website sich je nach Zeit ändert. Also dass ich einstellen kann, welches Bild zum Beispiel von 06:00 Uhr bis 12:00 Uhr, welches von 12:00 bis 18:00 Uhr und so weiter...., angezeigt wird..
Ich hatte schon ein script gefunden, nur das funktioniert nicht. Es wird kein Bild angezeigt. Das Script ist folgendes:

:<table width="350" border="0" cellspacing="0" cellpadding="0" bgcolor="000000" background="images/nav_nacht.jpg" height="650">
<tr height="439">
<td height="439"><script type="text/javascript">
<!--
now = new Date();
hour = now.getHours();
if (hour > 5 && hour < 10) {
document.write ("<IMG SRC = 'images/nav_morgen.jpg' width='350' height='439' BORDER = '0' ALT = 'Morning'>");
}
if (hour > 9 && hour < 13) {
document.write ("<IMG SRC = 'images/nav_vormittag.jpg' width='350' height='439' BORDER = '0' ALT = 'Day'>");
}
if (hour > 12 && hour < 17) {
document.write ("<IMG SRC = 'images/nav_mittag.jpg' width='350' height='439' BORDER = '0' ALT = 'Day'>");
}
if (hour > 16 && hour < 20) {
document.write ("<IMG SRC = 'images/nav_nachmittag.jpg' width='350' height='439' BORDER = '0' ALT = 'Day'>");
}
if (hour > 19 && hour < 23) {
document.write ("<IMG SRC = 'images/nav_abend.jpg' width='350' height='439' BORDER = '0' ALT = 'Evening'>");
}
if (hour > 22 && hour < 24) {
document.write ("<IMG SRC = 'images/nav_nacht.jpg' width='350' height='439' BORDER = '0' ALT = 'Night'>");
}
if (hour > 0 && hour < 6) {
document.write ("<IMG SRC = 'images/nav_nacht.jpg' width='350' height='439' BORDER = '0' ALT = 'Night'>");
}
// -->

</script></td>

Also vielen dank schon mal...
cheers

  1. Hallo Thomas,

    Kommt eine Fehlermeldung?
    Was wird überhaupt angezeigt?
    Ist Javascript eingeschaltet? Der IE schaltet schon mal Javascript ab, wenn die Seite von deiner Platte kommt.

    Zur Fehlersuche:

    Prüfe, ob das Bild existiert: img direkt ohne Javascript in der Tabelle
    Bild mit Javascript, aber ohne Zeitabfrage.
    Alerts an "strategisch günstigen" Stellen.

    Eine Anmerkung zu Deinen if-Konstrukt: Hast Du schon mal an if - else if ... - else gedacht?

    Gruß, Jürgen

    1. Also ich testete das jetzt nur von Platte. Vielleicht liegt es daran.

      Der Code ist aus einem anderen, älteren Forum rauskopiert...ich selber habe davon keinen rechten Dunst.

      Nach diesem script zeigt mir die Seite einen schwarzen Hintergrund und eben die Darstellung eines Bildes, das nicht geladen werden kann. (also heller Rahmen und das kleine Bildsymbol in der Ecke).
      wenn es aber ein Script oder sowas gäbe, mit dem ich Hintergrundbilder ändern könnte, dann wäre das noch besser..

      1. Hallo Thomas,

        die Lösung über document.write ist nicht "elegant", aber wenn nur beim Laden ein Element angepasst werden soll, ist es schon ok.

        Wenn Du kein Bild siehst, ist entweder Javascript abgeschaltet, oder die URL des Bildes ist falsch. Setze mal vor das if ein alert("Javascript ist an! Stunde:"+hour);

        Wenn Du den Hintergrund der ganzen Seite ändern möchtest, kannst Du den body-Tag mit document.write schreiben. Dann solltest du aber im <noscript>-Bereich ein "Default-Body" stehen haben:

        <script type="text/javascript">
         ....
         document.write("<body style='background-image:url(mit_js.gif)'>");
         ....
        </script>
        <noscript>
         <body style='background-image:url(ohne_js.gif)'>
        </noscript>

        Das ist jetzt nicht getestet und soll nur als einfaches Beispiel dienen. Auch wirst du nicht umhin kommen, ein wenig Javascript-, HTML- und CSS-Basics zu lernen.

        Alternativ und viel eleganter könntest du auch per "window.onload" eine Funktion starten, die zeitabhängig "document.body.style.backgroundImage" ändert, also im Kopf der Seite:

        window.onload=function() {
         ... Zeitabfrage, if, ...
         document.body.style.backgroundImage=...;
        }

        Um die Seite lokal testen zu können, setze entweder den Firefox ein (meine Empfehlung) oder siehe http://aktuell.de.selfhtml.org/artikel/sonstiges/markoftheweb/index.htm.

        Gruß, Jürgen

  2. Hello out there!

    Wie erreiche ich, dass ein Hintergrund meiner Website sich je nach Zeit ändert.

    War das eine Frage.

    Es wird kein Bild angezeigt.

    Groß-/Kleinschreibung im Pfad-/Dateinamen beachtet? Pfad richtig?

    document.write ("<IMG SRC = 'images/nav_morgen.jpg' width='350' height='439' BORDER = '0' ALT = 'Morning'>");

    document.write() ist nicht gerade state of the art. Aber sag mal, wolltest du nicht ein _Hintergrund_bild?

    Wie du CSS-Eigenschaften änderst, findest du in http://de.selfhtml.org/javascript/objekte/style.htm beschrieben.

    See ya up the road,
    Gunnar

    --
    „Wer Gründe anhört, kommt in Gefahr nachzugeben.“ (Goethe)
  3. Hallo,

    Wie erreiche ich, dass ein Hintergrund meiner Website sich je nach Zeit ändert. Also dass ich einstellen kann, welches Bild zum Beispiel von 06:00 Uhr bis 12:00 Uhr, welches von 12:00 bis 18:00 Uhr und so weiter...., angezeigt wird..

    Javascript ist nicht gerade die beste Methode dafür. Normalerweise nimmt man dazu einer serverseitige Programmiersprache wie PHP oder eine CGI-Anwendung, die einfach schon den passenden HTML-Quellcode an den Browser sendet. Vorteil: Im Browser muss nichts mehr berechnet werden und kann somit auch nicht schief gehen, weil z.B. JS ausgeschaltet ist. Im wesentlichen ist es schlechter Stil, einfach so zu versuchen mit JS HTML-Quellcode im Browser live zu schreiben.

    Nun kann nicht jeder serverseitige Programmiersprachen oder hat diese auf seinem Webspace zur Verfügung. Deswegen skizziere ich hier mal ein paar Möglichkeiten, auch so zurecht zu kommen.

    Server Side Includes sind eine recht billige Variante etwas Dynamik in Seiten zu kriegen und sind praktischerweise bei den allermeisten Webspace-Angeboten dabei. Man schreibt winzige Kommentar-Anweisungen in eine HTML-Datei mit der Endung *.shtml. Der Webserver verarbeitet diese und ersetzt sie durch die Ausgabe dieser Anweisungen. Unter anderem kann auch das Datum ausgegeben werden. Wenn ich z.B. folgende SSI-Anweisung in test.shtml schreibe ...

    <p>Datum: <!--#echo var="DATE_LOCAL" --></p>

    ... kommt in meinem Browser dieses an ...

    <p>Datum: Friday, 17-Aug-2007 14:30:09 CEST</p>

    Das ist schon der aktuelle Zeitstempel zum Ausliefern der Webseite. Nur das Format passt noch nicht so ganz. Aber dieses kann man mit der #config-SSI-Anweisung beeinflussen. Schreibe ich dieses ...

    <p>Stunde: <!--#config timefmt="%H" --><!--#echo var="DATE_LOCAL" --></p>

    ... kommt im Browser jenes an:

    <p>Datum: 14</p>

    „12“, weil es gerade zwei Uhr irgendwas ist. Der Platzhalter „%H“ sagt, dass an dieser Stelle nur den Stundenteil der aktuellen Uhrzeit ausgegeben werden soll. Das heisst, man hat jetzt die Möglichkeit automatisiert durch den Webserver die aktuelle Stunde (von „00“ bis „23“) in den HTML-Quelltext reinzupacken. An jeder Stelle. Nehmen wir mal diese Anweisung:

    <p><img src='stunde-<!--#config timefmt="%H" --><!--#echo var="DATE_LOCAL" -->.jpg' alt="..."></p>

    Klarer wird es in der Ausgabe:

    <p><img src="stunde-14.jpg" alt="..."></p>

    Die „12“ von gerade ist hier also Bestandteil einer Bild-URL. Man hat also automatisch immer eine zur Uhrzeit passende Bild-URL in seinem HTML stehen.

    Ein Nachteil: Wenn man wie Du den Tag in Zeitspannen wie Morgens, Vormittags, etc. einteilt dann muss man trotzdem 24 Bilder anlegen bzw. kopieren und umbenennen:

    • stunde-00.png   • stunde-01.png   • ...   • stunde-23.png

    Das ist etwas nervig und wenn man Speicherplatzprobleme haben sollte (Heute noch?) auch etwas verschwendend. Eine Möglichkeit ist es, die Requests auf die 24-Stunden-URLs auf passende Bilder umzuleiten. Das macht man beim Webserver in in einer .htaccess-Datei mit mod_rewrite. Die Umleitungsregel für Morgens könnte dann z.B. so aussehen:

    RewriteRule ^stunde-(06|07|08|09|10)\.png$ morgens.png

    Problem: mod_rewrite ist manchmal nicht bei Billig-Webspace aktiviert. Und so Umleitungsregeln können manchmal sehr kompliziert werde, weil Reguläre Ausdrücke benutzt werden, die manchmal stark Schwarzer Magie ähneln.

    ...

    Eine andere Lösung. Wir nutzen immer noch SSI, aber statt img-Elemente CSS. Denn eigentlich willst Du ja _Hintergrund_bilder haben, keine Vordergrundbilder. Der HTML-Quellcode für eine Tabellenzelle sieht jetzt ungefähr so aus:

    <td id="tageszeitlogo"> sonstiger Inhalt </td>

    Hintergrundbilder werden mit CSS so deklariert:

    td#tageszeitlogo {
          background-image:url(default.png);
      }
    

    Dies ist allgemeines Hintergrundbild für Deine Tabellenzelle, das nur benutzt wird, wenn keine spezifischere CSS-Regel zutrifft (oder SSI gerade nicht funktioniert – eine praktische Fehlerbehandlung). Wie z.B. spezifischere tageszeitabhängige Regeln. Hier ist mal so eine:

    body.stunde-12 td#tageszeitlogo {
          background-image:url(mittags.png);
      }
    

    Übersetzt: Wenn die Tabellenzelle mit der ID „tageszeitlogo“ sich innerhalb eines body-Elementes mit der Klasse „stunde-12“ befindet, dann weise das Hintergrundbild „mittags.png“ zu. Diese Selektoren kann man auch kombinieren und damit mehrere Regeln zusammenstellen. Hier mal die Logik Deines Skriptes in der CSS-Variante ausgedrückt:

    body.stunde-23 td#tageszeitlogo,
      body.stunde-00 td#tageszeitlogo,
      body.stunde-01 td#tageszeitlogo,
      body.stunde-02 td#tageszeitlogo,
      body.stunde-03 td#tageszeitlogo,
      body.stunde-04 td#tageszeitlogo,
      body.stunde-05 td#tageszeitlogo {
          background-image:url(images/nav_nacht.jpg);
      }
    
      body.stunde-06 td#tageszeitlogo,
      body.stunde-07 td#tageszeitlogo,
      body.stunde-08 td#tageszeitlogo,
      body.stunde-09 td#tageszeitlogo {
          background-image:url(images/nav_morgens.jpg);
      }
    
      body.stunde-10 td#tageszeitlogo,
      body.stunde-11 td#tageszeitlogo,
      body.stunde-12 td#tageszeitlogo {
          background-image:url(images/nav_vormittag.jpg);
      }
    
      body.stunde-13 td#tageszeitlogo,
      body.stunde-14 td#tageszeitlogo,
      body.stunde-15 td#tageszeitlogo,
      body.stunde-16 td#tageszeitlogo {
          background-image:url(images/nav_mittag.jpg);
      }
    
      body.stunde-17 td#tageszeitlogo,
      body.stunde-18 td#tageszeitlogo,
      body.stunde-19 td#tageszeitlogo {
          background-image:url(images/nav_nachmittag.jpg);
      }
    
      body.stunde-20 td#tageszeitlogo,
      body.stunde-21 td#tageszeitlogo,
      body.stunde-22 td#tageszeitlogo {
          background-image:url(images/nav_abends.jpg);
      }
    

    Sieht nach viel aus, aber man muss es nur einmal schreiben (idealerweise mit einfachereren Bezeichnern) und kann das dann jederzeit umordnen. Alles hängt nun wieder daran, dass das body-Element nun die Klasse „stunde-XX“ bekommt. Und dies geschieht wieder mit SSI:

    <body class="stunde-<!--#config timefmt="%H" --><!--#echo var="DATE_LOCAL" -->">

    Ausgabe, gerade:

    <body class="stunde-13">

    Diese Ausgabe wird automatisch durch den Webserver erstellt, kommt so beim Browser an. Und der Browser braucht dann einfach nur noch die aktuell passende CSS-Regel aus dem Stylesheet zu fischen und anzuwenden.

    Kleiner Exkurs: Warum die Uhrzeit am body-Element und nicht an der Tabellenzelle? Ganz einfach: Durch die Verschachteltung kann man diese Information auch wunderbar in anderen Teilen des Dokumentes nutzen, denn diese befinden sich alle unterhalb des body-Elementes. Wenn man in der Geisterstunde z.b. alle Links rot färben will, genügt diese einfache Regel:

    body.stunde-00 a:link {
          color:red;
      }
    

    Durch passende Positionierung der Informationen ist sie global nutzbar.

    ...

    Und was ist, wenn man weder serverseitige Techniken und auch nicht eine Billig-Technik wie SSI nutzen kann? Dann bleibt einem letztendlich nichts übrig, als Javascript im Browser zu nutzen.

    Ich halte es aber für eine schlechte und eher unwartbare Idee, mitten im HTML-Quelltext mit document.write automatisch generierten Quellcode zu schreiben. Ich würde viel eher die CSS-Regeln von gerade einfach weiter zu nutzen, der Großteil der Logik steckt da schon drin und kann leicht verändert werden. Alles was JS noch übrig bleibt, ist die Klasse „stunde-XX“ an das body-Element dran zu setzen. Und wenn JS deaktiviert ist, wird das default-Hintergrundbild angezeigt - ohne dass es zu hässlichen Fehlern kommt.

    Erstmal im Kopf der Seite eine Funktion definieren, die dem body-Element das passende Attribut verpasst:

    function setHour() {
          var classes = document.body.attributes["class"].value.split(" ");          // 1
          var newClasses = [];                                                       // 2
          for (var i = 0; i < classes.length; i++) {                                 // 3
              if (!classes[i].match(/stunde\-\d\d/)) {                               // 4
                  newClasses.push(classes[i])
              };
          };
    
          var hour = new Date().getHours().toString();                               // 5
          var actualClass = "stunde-" + ((hour.length == 1) ? ("0" + hour) : hour);  // 6
          newClasses.push(actualClass);                                              // 7
    
          document.body.attributes["class"].value = newClasses.join(" ");            // 8
      }
    

    Durchkommentiert:

    1. Wir wollen dem body-Element eine neue Klasse anhängen oder austauschen. Dazu brauchen wir erstmal die Klassen in einem passenden Format. document.body greift auf das body-Element zu, attributes["class"].value liefert den Inhalt des class-Attributes als String und die String-Methode split() trennt diesen String an den Leerzeichen in ein Array auf. Für den HTML-Code <body class="eins zwei drei"> erhalten wir also dieses Javascript-Array: ["eins", "zwei", "drei"].

    2. Wenn man Klassen verändert will, empfiehlt es sich oft, eine neue Sammlung von Klassen aufzubauen. Hier wird also ein neues, noch leeres Array namens newClasses deklariert.

    3. Jetzt wird in einer Schleife jedes Klasse des alten Klassen-Arrays durchgegangen.

    4. Wenn die Klasse nicht auf das Muster „stunde-<Zahl><Zahl>“ passt (überprüft mit der String-Methode match() und einem Regulären Ausdruck, dann wird die Klasse an das neue Klassen-Array angehängt. Das hat den Vorteil, dass Klassen wie „stunde-XX“ rausgefiltert werden. Man will ja immer nur die aktuelle „stunde-XX“-Klasse am Body haben. Alte könnten z.B. durch die SSI-Initialisierung kommen oder ... dazu komme ich gleich.

    5. Jetzt kümmern wir uns um die neue Uhrzeit-Klasse. Zuerst braucht man den Stundenteil der aktuellen Uhrzeit. new Date() erzeugt ein neues Datum-Objekt mit der aktuellen Uhrzeit. Dessen Methode getHours() liefert den Stundenanteil als Zahl zurück, deren Methode toString() verwandelt eine Zahl in einen String wie "1".

    6. Hier wird der tatsächliche Text-String der neuen Klasse erzeugt, damit das Muster „stunde-XX“ entsteht. Der feste Bestandteil "stunde-" wird mit der Stunde zusammengefügt. Allerdings ist da ein Sonderfall: Die Methode toString() von Schritt Fünf liefert als Zahl nur eine Stelle zurück, wenn die Zahl nur aus einer Stelle besteht. Für 9 Uhr also "9". Die SSI-Variante schreibt 9 Uhr aber als "09" und so habe ich auch das „stunde-XX“-Muster definiert. Ich nutze hier den Ternären Operator für ein Entweder-Oder-Ausdruck: Wenn die Länge des Stunden-Strings nur ein Zeichen beträgt ("9"), wird noch eine Null vorne dran gefügt. Wenn nicht (also zwei Zeichen wie "14", wird der Stunden-String einfach so zurück gegeben. Und dieses wird dann mit "stunde-" zu "stunde-09" verknüpft.

    7. Hier wird die neu erstellte, aktuelle Klasse an das neue Klassen-Array angehängt.

    8. Damit das alles wirksam wird, müssen die Klassen auch wieder am body-Element wirksam werden. Dazu werden die Stringsim neuen Klassen-Array mit der Array-Methode join(" ") zu einem durch ein Leerzeichen getrennten String verknüpft. ["eins", "zwei", "stunde-14"] wird also zu "eins zwei stunde-14". Dieser String wird dann wieder dem class-Attribut des body-Elementes zugewiesen.

    Wirkt komplizierter als es ist. Der Knackpunkt ist es jetzt noch diese Funktion aufzurufen. Da gibt es verschiedene Varianten:

    setHour();

    Der direkte Aufruf hat ein Problem: Dieser Abschnitt von Javascript steht im Kopf der Seite und wird direkt aufgeführt. Zum Zeitpunkt des Ausführens kann es aber unwahrscheinlicherweise sein, dass der Browser beim Laden des Dokumentes noch nicht beim body-Element angelangt ist. Wenn die Funktion nach document.body fischen will, existiert dieses also eventuell noch gar nicht. Insofern ist das schlecht.

    window.onload = setHour

    Hier wird die onload-Methode des window-Objektes (es ginge auch body.onload) gleich der Funktion gesetzt. Wenn das Dokument also vollständig geladen ist, wird die onload-Methode ausgeführt und damit die Funktion. Diese Variante hat den ästhetischen Nachteil, dass der Nutzer dann das Dokument fertig geladen sieht und plötzlich und unerwartet sich etwas ändert, ein Flash.

    Idealerweise wird die Funktion direkt dann aufgerufen, wenn das body-Element schon vom Browser verarbeitet ist, aber der Rest des Dokumentes noch vor ihm liegt. Das wäre dann der praktische Einsatz für script-Elemente innerhalb des body-Elementes:

    <body>
          <script type="text/javascript">
               setHour();
          </script>
          <p>Ganz viel Restdokument</p>
      </body>
    

    ...

    Das Setzen der Uhrzeit-Klasse geschieht bislang nur einmal, direkt beim Laden des Dokumentes. Wenn aber nun ein Nutzer um 14:58 Uhr das Dokument lädt und um 15:00 ein Bildwechsel stattfinden soll, findet dieser nicht im live im Browser statt. Die Funktion wird ja nur einmal aufgerufen. Wenn man ganz perfektionistisch ist, kann man nun auch noch das Skript erweitern, so, dass ständig die aktuelle Uhrzeit-Klasse gesetzt wird. Oder nicht ständig aber jede Minute. Dieses kann man mit der Funktion setInterval() machen. Damit wird die wiederholte Ausführung einer Funktion für alle x Millisekunden gestartet:

    window.setInterval(setHour, 1000*60);

    Als Parameter gibt man setInterval einfach den Namen der aufzurufenden Funktion und den Zeitabstand, hier 1000 Millisekunden mal 60 Sekunden, um auf eine Minute zu kommen. Und effektiv kann man jetzt auch auf das Script-Element im body verzichten.

    Viel Erfolg beim Anwenden.

    Tim

    --
    Ich hoffe, jetzt findet man was im Archiv.