map und onmouseover
Pati
- html
Hallo,
also ich habe folgendes Problem.
Habe ein Foto als map mit 3 verschiedenen areas.(Nur bestimmte Bereiche innerhalb des Bildes sind anklickbar)
Jetzt möchte ich, dass wenn ich über den ersten Bereich fahre, an einer anderen Stelle ein Text mit Bild angezeigt wird.
Und wenn ich über den 2.Bereich fahre, soll ein ganz anderer Text als vorher und ein anderes Bild erscheinen.
Kann ich das ohne Java realisieren?
Mit dem onmouseover hab ich es schon versucht, aber ich bekomme es nicht hin, dass es bei jeder area einen anderen Text anzeigt!
Mit hover habe ich es auch versucht. Der Text mit dem Bild wird problemlos eingeblendet, jedoch immer der Gleiche und ich brauche ja für jeden Bereich einen anderen...
Ich hoffe, dass ich mich nicht zu kompliziert ausgedrückt habe, wusste nicht, wie ich es besser erklären sollte...
Wäre für Vorschläge sehr dankbar! Muss noch dazu sagen, dass ich Anfänger bin.
@@Pati:
Kann ich das ohne Java realisieren?
Ohne http://de.selfhtml.org/intro/technologien/java.htm@title=Java? Ja. Mit http://de.selfhtml.org/javascript/intro.htm@title=JavaScript.
Ohne JavaSript? Mit CSS? Nein.
Live long and prosper,
Gunnar
Mit dem onmouseover hab ich es schon versucht, aber ich bekomme es nicht hin, dass es bei jeder area einen anderen Text anzeigt!
Woran haperts? Wie sieht dein Quellcode aus?
Ich würde es konzeptionell so lösen:
HTML:
<map id="map" ...>
<area href="#aaa" ...>
<area href="#bbb" ...>
...
</map>
<ul id="erklärungen">
<li id="aaa">
<h2>Erklärung</h2>
<p>Text</p>
</li>
<li id="bbb">
<h2>Weitere Erklärung</h2>
<p>Weiterer Text</p>
</li>
...
</ul>
Im HTML die Map definieren und den Areas ein Linkziel geben. Wenn JavaScript deaktiviert ist, kann man darüber zu den Infos springen. Die liegen in einem ul-Element darunter, schön sortiert, schön mir IDs versehen. Die hrefs der Areas zeigen auf diese IDs.
CSS:
.javascript-aktiv #erklärungen li {
display:none;
}
.javascript-aktiv #erklärungen li.sichtbar {
display:block; /* oder list-item, wurscht */
}
Mit CSS formatierst und positionierst du das ganze, hier nur die wichtigen Regeln zum Ein- und Ausblenden der Inhalte. Wenn JavaScript aktiv ist, bekommt das body-Element eine Klasse. Über die erste Regel werden also bei aktiviertem JavaScript die li-Elemente versteckt. Wenn sie jedoch die Klasse sichtbar haben, sollen sie angezeigt werden.
JavaScript:
window.onload = function () {
document.body.[ref:self812;javascript/objekte/htmlelemente.htm#universaleigenschaften@title=className] = "javascript-aktiv";
var map = document.[ref:self812;javascript/objekte/document.htm#get_element_by_id@title=getElementById]("map");
map.onmouseover = areaMouseover;
map.onclick = areaMouseover;
};
function areaMouseover () {
if (!this.hash) return;
var id = this.[ref:self812;javascript/objekte/location.htm#hash@title=hash].[ref:self812;javascript/objekte/string.htm#substring@title=substring](1);
var el = document.getElementById(id);
el.className = "sichtbar";
if (areaMouseover.aktivesElement) {
areaMouseover.aktivesElement.className = "";
}
areaMouseover.aktivesElement = el;
}
function areaClick () {
return false;
}
Das JavaScript fügt sich automatisch nach dem Laden des Dokuments hinzu. Im onload wird erstmal die CSS-Klasse gesetzt, wodurch die li-Elemente verschwinden. Dann werden dem map-Element zwei Event-Handler für click und mouseover gegeben. Diese verarbeiten alle Ereignisse, die von den verschiedenen area-Elementen aufsteigen. Sprich, ein zentraler Event-Handler an einem übergeordneten Element für mehrere Areas.
Im Mouseover-Handler wird die hash-Eigenschaft des angeklickten area-Elementes ausgelesen. (Wenn das angeklickte Element keine solche Eigenschaft hat, wird die Funktion einfach direkt beendet.) Der »Hash« ist ein Teil der URL aus dem href-Attribut, nämlich der Teil »#aaa«. (Man könnte auch einfach this.href nehmen, allerdings wäre da die gesamte Adresse des aktuellen Dokuments auch noch mit drin.) Wenn man das erste Zeichen noch wegnimmt, kommt man schließlich zu »aaa« und kann das zugehörige Element über diese ID ansprechen.
Das zugehörige Element wird schließlich eingeblendet, indem es die Klasse »sichtbar« bekommt. Damit immer nur ein Element eingeblendet sein kann, wird das gerade aktive Element zwischengespeichert in der Objekteigenschaft areaMouseover.aktivesElement. Wenn da bereits ein Element drinsteht (also schon einmal eine Erklärung eingeblendet wurde), wird diesem die Klasse weggenommen.
Der Klick-Handler macht nichts anderes, als die Standardaktion zu unterdrücken. Zweck davon ist, dass der Browser beim Klick auf die Area nicht zusätzlich zum eingeblendeten li-Element springt - weil die ist auch Linkziel. Das ist, je nachdem, wie du die Elemente positionierst, nicht unbedingt schlimm - dann könntest du den Teil weglassen.
Das jetzt nur als ungetestetes(!) Konzept(!)beispiel, wie du die Inhalte sauber strukturiert im HTML notieren kannst und sie auch ohne JavaScript zugänglich sind. Schau es dir mal an, versuche die grundlegende Funktionsweise zu verstehen und prüfe, ob das Konzept auf deine Anwendung passt. Falls ja, versuche es anzupassen, dabei kann ich dir gerne nochmal helfen.
Mathias
map.onclick = areaMouseover;
Das muss natürlich
map.onclick = areaClick;
heißen.
Das Schema sollte aber klar geworden sein. Alle weiteren Fehler sind absichtlich eingebaut und didaktisch wertvoll! ;)
Hallo molily,
Ich würde es konzeptionell so lösen:
Eine tolle Anleitung! Aber eine kleinigkeit würde ich doch ändern. Statt
CSS:
.javascript-aktiv #erklärungen li {
display:none;
}
besser
~~~css
.javascript-aktiv #erklärungen li {
position: absolute;
left: -1000px;
top:-1000px;
width:0px;
height: 0px;
overflow:hidden;
display:inline;
}
tastatur-Nutzer haben dann allerdings immer noch ein Problem - denn onClick und onMouseOver werden sie niemals triggern...
Viele Grüße,
Marc.
Hi,
tastatur-Nutzer haben dann allerdings immer noch ein Problem - denn onClick und onMouseOver werden sie niemals triggern...
MouseOver vielleicht nicht - aber onclick feuert auch beim "aktivieren" eines Elementes mit der Tastatur.
MfG ChrisB
Aber eine kleinigkeit würde ich doch ändern.
Danke für den sehr nützlichen Hinweis.
tastatur-Nutzer haben dann allerdings immer noch ein Problem - denn onClick und onMouseOver werden sie niemals triggern...
Ja, wenn ich Zeit habe, werde ich noch ein funktionsfähiges Beispiel machen, das Tastaturbedienung berücksichtigt.
Ein area ist glücklicherweise fokussierbar, da dürfte es kein Problem sein, mit DOMFocusIn/focusin die Erklärungen einzublenden.
Mathias
Das mit dem
map.onmouseover = areaMouseover;
function areaMouseover () {
if (!this.hash) return;
Das ist Unsinn. this verweist hier immer auf das map-Element, nicht das area-Element.
Es wäre zwar sehr elegant, alle Ereignisse der areas zentral beim map-Element »abhören« zu können, aber die besagte Methode mit den aufsteigenden focus-Events funktioniert nicht so ohne weiteres browserübergreifend. Das hatte ich hier mal geschildert:
</archiv/2008/10/t178060/#m1173789>
Für vier Browser bräuchte man drei unterschiedliche Umsetzungen. Das lohnt sich hier nicht. Deshalb habe ich es dann Old-School gelöst und einfach allen area-Elementen im map-Element über eine Schleife die Handler zugewiesen.
Das hier sollte auch mit Tastatur-Bedienung funktionieren:
http://molily.de/temp/map-infos.html
Zusätzlich zu den Mouseovern wird auch der Focus-Event überwacht. Den Rest habe ich schon beschrieben. Hinzugekommen ist nur ein Abfrage beim Verstecken des letzten aktiven Elemente sowie die Ausblend-Logik beim Verlassen der Map.
Die Funktionen habe ich zudem in einem Object-Literal gruppiert.
Wenn du Fragen zum Beispiel hast, schieß los!
Mathias