Willkommen in der Webstatt Zum Webstatt Blog und Stories
Spark am 19.11.06 21:30

Hi!

Ich bin grad dabei mir mit JS ein Menü zu machen.
Ich habe dazu zwei DIVs (navi & menu). In dem ersten steht "Navigation" und beim onMouseOver wird der menu-DIV eingeblendet. Beide liegen genau aneinander. Beim onMouseOut vom navi-DIV soll das Menü wieder ausgeblendet werden, sofern man die Maus nicht über den menu-DIV gemacht hat! Beim onMouseOut vom menu-DIV soll dieser natürlich verschwinden.
Problem ist, dass ich das ganze rein und raus faden lasse. Also muss ich meiner Funktion irgendwie klar machen, dass ich beim onMouseOut vom navi-DIV und onMouseOver vom menu-DIV das ganze nicht erst ausblenden lassen möchte.
Wie mache ich das am besten?
Bis jetzt wird das Menü zwar eingeblendet, aber ich schaffe es nicht es da zu lassen wenn ich mit der Maus runter gehe :(

Wie schon im Titel erwähnt, bin JS noob und freue mich auch über verbesserungsvorschläge.

<html>
<head>
</head>
<body onLoad="slide('out')">
<script language="javascript" type="text/javascript">
var way;
var opacity = 0;
function slide(way) {
var delay = 50;
var object = document.getElementById('menu').style;
if(opacity == 0 && !way) {
way = "in";
} else if(opacity == 100 && !way) {
way = "out";
}
document.getElementById('menu').onmouseover = function() {
opacity = 100;
object.opacity = (opacity / 100);
object.MozOpacity = (opacity / 100);
object.KhtmlOpacity = (opacity / 100);
object.filter = "alpha(opacity=" + opacity + ")";
return;
};
object.opacity = (opacity / 100);
object.MozOpacity = (opacity / 100);
object.KhtmlOpacity = (opacity / 100);
object.filter = "alpha(opacity=" + opacity + ")";
if(way == "in") {
if(opacity < 100) {
opacity += 10;
setTimeout("slide('in', " + opacity + ")", delay);
}
}
if(way == "out") {
if(opacity > 0) {
opacity -= 10;
setTimeout("slide('out', " + opacity + ")", delay);
}
}
}
</script>
<div id="navi" style="position:absolute;bottom:50px;left:50px;width:200px;height:20px;background-color:#000000;" onMouseOver="slide()" onMouseOut="slide()" align="center"><font color="#FFFFFF"><b>N a v i g a t i o n</b></font></div>
<div id="menu" style="position:absolute;bottom:0px;left:0px;width:100%;height:50px;background-color:#000000;"></div>
</body>
</html>

netcup.de Warum gibt es hier Werbung?
tux am 27.11.06 18:01

Hi.

Erstmal vielen Dank für deinen Beitrag hier. Er hat mir dieses Forum gezeigt (wo ich mich nun prompt angemeldet habe ;) ) und meinem Gehirn einen Anstoß gegeben.

Als eine Art `Dankeschön´ möchte ich dir meine Vorschläge unterbreiten. Zuerst muss ich leider sagen, dass dein ganzes Skript beim Konqueror nicht funktioniert hat (benutze Version 3.5.1). Mein Firefox 2 hatte damit weniger Probleme; mal abgesehen von dem MouseOver Problem, das du beschrieben hast.
Auch nach meinen Änderungen funktioniert das Skript mit dem Konqueror nur teilweise.

Aber nun erstmal der Code

script.js
var way;
var opacity = 0;

function slide(way) {
var delay = 50;
var object = document.getElementById('menu').style;

if(!way) {
if(opacity == 0) {
way = "in";
} else if(opacity == 100) {
way = "out";
}
}

object.opacity = (opacity / 100);
object.MozOpacity = (opacity / 100);
object.KhtmlOpacity = (opacity / 100);
object.filter = "alpha(opacity=" + opacity + ")";

if(way == "in" && opacity < 100) {
object.visibility = "visible";
object.height = "auto";
opacity += 10;
setTimeout("slide('in')", delay);
}

if(way == "out" && opacity > 0) {
opacity -= 10;
setTimeout("slide('out')", delay);
}

if(opacity < 20) {
object.height = "0px";
object.visibility = "hidden";
}
}


Wie du siehst, habe ich die MouseOver-Funktion weggelassen und darüber hinaus den ersten Schwung If-Abfragen etwas umstrukturiert. Es wird nun zuerst überprüft, ob `way´ übergeben wurde. Das erspart - im Falle einer Übergabe - eine ganze If-Abfrage ;)

Auch die If-Abfragen, die das Verfahren bestimmen, habe ich zusammengefasst.
if (way == "in") { if(opacity < 100) { [arbeitsauftrag] } }
Das schien mir nicht sonderlich elegant ;)

In diese Abfrage habe ich noch etwas anderes eingefügt, nämlich
fade in
object.visibility = "visible";
object.height = "auto";

Die Gründe dafür sieht man in meinem Anwendungsbeispiel :)
Ausserdem noch eine neue If-Abfrage, die das Menü `verschwinden´ lässt:
nach fade out
if(opacity < 20) {
object.height = "0px";
object.visibility = "hidden";
}

Warum ich das nicht in den Fade-Out-Bereich gepackt habe? - Als ich es getestet habe, fiel mir auf, dass das Menü vor dem abgeschlossenen FadeOut verschwindet. Die Ursache dafür liegt meiner Meinung nach am SetTimeout();. `opacity < 20´ hat sich als nahezu optimaler Wert erwiesen, daher nicht 0. Darüberhinaus müssen sonst Konqueror-User noch einmal blinzeln, bis das Menü endlich verschwindet (wie erwähnt sehen diese weder den FadeIn-, noch den FadeOut-Vorgang).

Achja, wo wir gerade beim setTimeout()-Aufruf sind. Warum machst du ihn so:
setTimeout("slide('in', " + opacity + ")", delay);
slide() hat doch nur einen einzigen Parameter... opacity muss gar nicht übergeben werden (erscheint mir jedenfalls so)

Sooo. Zum Abschluss nun mein Anwendungsbeispiel. Kopiere es und wirf mal einen Blick darauf :)
<html>
<head>
</head>
<body>
<script src="script.js" type="text/javascript"></script>
<div>blablabalablabalablabal</div>
<div id="menu" style="background-color:#cf1;visibility:hidden;height:0px;">blablabla</div>
<div>blubbi billlablubbasoblabla</div>
<div id="navi" style="background-color:#000000;width:150px;" onClick="slide()" align="center"><font color="#FFFFFF"><b>Fade it, Baby!</b></font></div>
</body>
</html>


Der Firefox schafft dem Element nun den benötigten Platz und blendet es ein - bzw. aus und lässt es dann verschwinden. Der Konqueror schafft Platz, lässt es (leider ohne Fading) erscheinen und verschwinden. Wie es mit dem Internet Explorer aussieht weiß ich nicht, weil ich ihn als Linuxer nicht besitze ^_^

Noch weitere Vorschläge? Zusammen kriegen wir bestimmt noch mehr aus dem Skript raus (bin auch ein JS-Noob) :)

Cheers und schönen Abend,
-- tux.


[COLOR=crimson]Update[/COLOR]
Ich wollte letzte Nacht das ganze noch ein wenig verbessern. Vor allem hat es mich gestört, dass man nicht mehrere Elemente unabhängig voneinander behandeln konnte: Habe ich beispielsweise meine Newsbox eingeblendet, konnte ich nicht anschließend eine weitere Box einblenden, ohne vorher die Newsbox ausblenden zu lassen oder einfach 2x zu klicken. Das lag einerseits an der Variable `opacity´ und andererseits an `way´.
In dieser Version habe ich mit `display´ statt `visibility´ gearbeitet.

script.js//* Does not work properly in Konqueror 3.5.1 *//

function slide(eid,way) {
var delay = 50;
var object = document.getElementById(eid).style;

if(!object.opacity) {
object.opacity = (object.display=='block'?1:0);
}

if(!way) {
if(object.opacity == 0) {
way = "in";
object.display = "block";
} else if(object.opacity == 1) {
way = "out";
}
}

object.MozOpacity = object.opacity;
object.KhtmlOpacity = object.opacity;
object.filter = "alpha(opacity=" + (object.opacity * 100) + ")";

if(way == "in" && object.opacity < 1) {
object.opacity = parseFloat(object.opacity)+0.1;
setTimeout("slide('"+ eid +"', 'in')", delay);
}else if(way == "out" && object.opacity > 0) {
object.opacity -= 0.1;
setTimeout("slide('"+ eid +"', 'out')", delay);
}

if(object.opacity < 0.1) {
object.display = "none";
}
}

function fadeIni() {
document.getElementById('box1').style.display = "none";
document.getElementById('box2').style.display = "block";
// etc...
}


Ich musste `parseFloat()´ benutzen, da sonst beim Einblenden `0.1´ als String angefügt wurde.
Der Konqueror kommt nun leider gar nicht mehr damit klar. Aber ich bin zuversichtlich, dass sich da eine Lösung finden wird.

Creative Commons Lizenzvertrag
Alle Inhalte des Webstatt-Archivs stehen unter einer Creative Commons Namensnennung - Weitergabe unter gleichen Bedingungen 3.0 Unported Lizenz.

Impressum & Kontakt