Vinzenz Mai: Wie das mouseover Script auf der Seite wiederholen?

Beitrag lesen

Hallo,

Du hast Hinweise bekommen, die für mich hilfreich wären. Ich befürchte (aus eigener Erfahrung in einem völlig anderen Bereich), dass sie Dich nicht besonders viel weitergebracht haben, weil ...

da ich JS Anfängerin bin, blick ich kaum durch.

... wir Dich vermutlich nicht dort abgeholt haben, wo Du stehst. Felix schreibt in seinem Artikel selbst, dass er mehrere Jahre intensiven Mitlesens, Ausprobieren und Lernens benötigt hat, um dort anzukommen, was er in seinem (sehr guten!) Artikel zu vermitteln versucht.

Ich glaube, für jeden ist es wichtig, Erfolgserlebnisse zu haben. Diese motivieren mich, weiterzumachen, dazuzulernen - und sei es nur für mich selbst.

Ich möchte: Genau dieses mouseover Bildarstellung (oben) 3x auf der Seite haben.

Das kriegst Du hin!

Ich möchte es auf die relevanten Bereiche reduzieren:

Dokumententyp:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">

Javascript:

» var bild1 = new Image();

// Dieser erste Abschnitt dient dazu, Bilder vorzuladen.


> var bild2 = new Image();
> var bild3 = new Image();
> var bild4 = new Image();
> var bild5 = new Image();
> var bild6 = new Image();
> bild1.src = "/bilder/hof_1.jpg";
> bild2.src = "/bilder/hof_2.jpg";
> bild3.src = "/bilder/hof_3.jpg";
> bild4.src = "/bilder/hof_4.jpg";
> bild5.src = "/bilder/hof_5.jpg";
> bild6.src = "/bilder/hof_6.jpg";

// Wie Matthias zu Recht anmerkt, verwendest Du genau diese Bilder sowieso
// in Deiner Voransicht. Vorladen dieser Bilder ist somit überflüssig.


// Die folgende Funktion kann man leicht vereinfachen


> function Vorschau(VorschauGrafik)
> {
> eval("document['picture'].src = " + VorschauGrafik + ".src");
> }

Solchen Code wie in Deiner Funktion "Vorschau" fand man auch in älteren Ausgaben von SELFHTML. Überflüssigerweise wird von der Funktion eval() Gebrauch gemacht. Zu [ref:self812;javascript/objekte/unabhaengig.htm#eval@title=eval()] gibt es einen einfachen Merksatz (Ausnahmen bestätigen wie üblich die Regel):

"eval is evil."

Abgesehen davon verzichten wir auf das Vorladen der Vorschaugrafiken und haben daher keine Notwendigkeit, auf eval() zuzugreifen. Sogar der erste Schritt, um mehrere Vorschaubilderlisten in einem Dokument haben zu können, bringt und keinen komplexeren, sondern sogar einfacheren Code.

HTML

Zielbereich der Großdarstellung:

<div id="box5"> <img class="Bild" name="picture" src="/bilder/hof_1.jpg" width="350" height="273" border="0" alt=""> </div>

Wie ich bereits anmerkte, ist dies der Zielbereich für Deine Darstellung. Statt dem img-Element ein name-Attribut zu geben, wäre es sinnvoller, diesem ein id-Attribut zu geben, anhand dessen Du das Zielelement identifizieren kannst - ganz besonders, weil das name-Attribut bei img-Elementen auf der Abschussliste steht. In XHTML 1.0 strict ist es beispielsweise schon seit fast 10 Jahren nicht mehr zulässig.

[...]

Vorschaubilder, die bei MouseOver im Zielbereich dargestellt werden sollen:

» <a href="derhof.htm" onMouseOver="Vorschau('bild1')"><img src="/bilder/hof_1.jpg" alt="" border="0" width="120" height="94"><a>

> <a href="derhof.htm" onMouseOver="Vorschau('bild2')"><img src="/bilder/hof_2.jpg" alt="" border="0" width="120" height="94"><a>
> <a href="derhof.htm" onMouseOver="Vorschau('bild3')"><img src="/bilder/hof_3.jpg" alt="" border="0" width="120" height="94"><a><br />
> <a href="derhof.htm" onMouseOver="Vorschau('bild4')"><img src="/bilder/hof_4.jpg" alt="" border="0" width="120" height="94"><a>
> <a href="derhof.htm" onMouseOver="Vorschau('bild5')"><img src="/bilder/hof_5.jpg" alt="" border="0" width="120" height="94"><a>
> <a href="derhof.htm" onMouseOver="Vorschau('bild6')"><img src="/bilder/hof_6.jpg" alt="" border="0" width="120" height="94"><a>

Bitte beachte, dass der von Dir genutzte Event-Handler [ref:self812;javascript/sprache/eventhandler.htm#onmouseover@title=onmouseover] und nicht onMouseOver heißt.

Fassen wir zusammen, was Deine Anforderung ist: Beim Event onmouseover soll das Bild, über dem die Maus sich gerade befindet, in einem Zielbereich angezeigt werden. Unterschiedliche Bildlisten sollten in unterschiedlichen Zielbereichen angezeigt werden.

Da das Vorschaubild das gleiche ist wie das, das im Zielbereich angezeigt werden soll, können wir sehr einfachen Code schreiben. Wie Du anhand meiner bisherigen Argumentation entnehmen kannst, müssen wir der Funktion, die die Arbeit erledigen soll, den Zielbereich angeben können, d.h. die Funktion benötigt nicht nur die Information, was sie anzeigen soll, sondern auch die Information, wo sie das anzeigen soll:

/**
 Übergabeparameter:
 picture:   Verweis auf das Bild, das angezeigt werden soll
 targetid:  id des img-Elementes, in dem das Bild angezeigt werden soll
 */
function Vorschau(picture, targetid)

Daher müssen wir den HTML-Quellcode auch leicht modifizieren:

Zielbereich der Großdarstellung der ersten Bilderliste. Diese zeigt Bilder zum Hof, deswegen geben wir dem Bild, d.h. dem img-Objekt die id "phof". Andere Zielbereich benötigen selbstverständlich eine andere id.

<div id="box5">
  <img class="Bild" id="phof" src="/bilder/hof_1.jpg" width="350" height="273" border="0" alt="">
</div>

<!-- [...]
Beachte:
ich habe die img-Elemente XHTML-konform geschlossen und auch die a-Elemente korrekt geschlossen.
Auf onmouseover reagieren wir derzeit noch nicht, das kommt im nächsten Schritt.
-->
<a href="derhof.htm"><img src="/bilder/hof_1.jpg" alt="" border="0" width="120" height="94" /></a>
<a href="derhof.htm"><img src="/bilder/hof_2.jpg" alt="" border="0" width="120" height="94" /></a>

Unsere Vorschaufunktion benötigt einen Verweis auf das Bild, das in Großansicht gezeigt werden soll: dieses ist ja identisch mit dem Vorschaubild, das im Vorschaubereich vom Browser kleiner skaliert wird. Es ist daher sinnvoll, auf den onmouseover-Event des Bildes zu reagieren, ganz besonders, weil uns Javascript das spezielle Schlüsselwort [ref:self812;javascript/sprache/objekte.htm#this@title=this] zur Verfügung stellt, mit dem auf das aktuelle Element Bezug genommen wird:

Modifizieren wir unseren HTML-Code mit fest verdrahteten Event-Handlern [1]:

<a href="derhof.htm"><img src="/bilder/hof_1.jpg" alt="" border="0" width="120" height="94" onmouseover="Vorschau(this, 'hpic')"/></a>
<a href="derhof.htm"><img src="/bilder/hof_2.jpg" alt="" border="0" width="120" height="94" onmouseover="Vorschau(this, 'hpic')" /></a>

Innerhalb einer Bilderliste verwenden wir stets den gleichen Funktionsaufruf. Dabei ist der erste Parameter stets ein Verweis auf das aktuelle Objekt, das heißt, das Bild, das den Event ausgelöst hat. Der zweite Parameter ist die id des Zielelementes.

Implementieren wir nun die Funktion Vorschau:

function Vorschau(picture, targetid) {
    // picture ist ein Verweis auf ein img-Element.
    // img-Elemente haben ein src-Attribut, das uns in Javascript
    // als Element-Eigenschaft zur Verfügung steht:

    // Verschaffen wir uns Zugriff auf das Zielelement:
    // Wir haben die id des Zielelementes, daher können wir die
    // Methode getElementById() verwenden.
    var target = document.[ref:self812;javascript/objekte/document.htm#get_element_by_id@title=getElementById](targetid);

    // Dieses ist ein img-Element, wie oben erwähnt haben solche ein
    // src-Attribut, das den Pfad zur Bildressource angibt.
    // Du möchtest im Zielelement das gleiche Bild anzeigen, das gerade
    // überfahren wird. Nichts einfacher als das:

    [ref:self812;javascript/objekte/images.htm#src@title=target.src] = picture.src;
}

Beachte: Alle Zeilen zum Vorladen der Bilder sind bei meiner Lösung überflüssig und können entfallen.

Modifikation: Da wir nur ein einziges Mal auf das Zielelement zugreifen, können wir und das Zuweisen an eine Variable sparen und kommen wie das Original mit einer einzigen Codezeile aus:

function Vorschau(picture, targetid) {
    document.getElementById(targetid).src = picture.src;
}

Mehr Javascriptcode benötigst Du für Dein Problem hier überhaupt gar nicht. Du solltest sehen, dass mein Vorschlag einfacher ist als das, was Du bisher hast.

Nehmen wir an, Du hast einen weiteren Bereich, in dem ein Bild aus einer zweiten Bilderliste angezeigt werden soll:

Ziel für Großanzeige 2:

<div id="box5b"><img id="spic" src="/bilder/schnaps.jpg" alt="" border="0" width="250" height="192"></div>

Vergib dem img-Element eine geeignete id, ich wählte

id="spic"

weils um Schnaps geht :-)

und die entsprechende Bilderliste:

<a href="demo.htm"><img src="/bilder/schnaps_1.jpg" alt="" border="0" width="120" height="94" onmouseover="Vorschau(this, 'spic')"/></a>
<a href="derhof.htm"><img src="/bilder/schnaps_2.jpg" alt="" border="0" width="120" height="94" onmouseover="Vorschau(this, 'spic')" /></a>

Du siehst, ich habe im onmouseover-Eventhandler diesmal bei allen Bildern

'spic'

übergeben, die id, die ich vorher dem Ziel-img-Element gegeben hatte. Die modifizierte Funktion sorgt dafür, dass das überfahrene Bild im richtigen Zielbereich angezeigt wird.

Ich hoffe, Du kannst meine Anregungen umsetzen und daraus die Motivation beziehen, Dich intensiver mit Javascript auseinanderzusetzen. Du wirst es Dir selber danken.

Weitere Schritte: Falls Du Thumbnails für die Voransicht verwendest (ich würde hier darauf verzichten), wird es etwas komplizierter. Code auslagern wäre ein weiterer Schritt und zum Schluss käme das Zuweisen der Eventhandler auch skriptgesteuert, so dass in Deinem HTML kein Inline-Javascript mehr wäre. Danach wirfst Du das Inline-CSS heraus (wie Dir schon angeraten wurde), entsorgst Leichen wie das font-Element. Dein HTML-Code wird schlanker, lesbarer und übersichtlicher werden - was der Wartbarkeit zu Gute kommen wird.

Das musst Du nicht auf einmal erledigen, Rom ist nicht an einem Tag erbaut worden - und auch wir™ haben nicht von Anfang an perfekten Code geschrieben [2].

Freundliche Grüße

Vinzenz

[1] Schritt für Schritt. [2] und tun dies heute auch noch nicht.