Ergebnis 1 bis 11 von 11
  1. #1
    Xenon ist offline Jungspund
    registriert
    23-11-2005
    Beiträge
    11

    Question javascript: menüs aufgleiten lassen?

    hi there!

    ich habe eine frage, bei der ich einfach nicht weiterkomme

    ich will ein aufklappendes menü realisieren wie zB auf http://www.vbulletin.com/forum/ beim klick auf "search" zu sehen ist.

    leider klappt es absolut nicht mit javascript und auch mit den verwendeten divs hab ich probleme (css). selfhtml hab ich schon erfolglos durchforstet und auch das ein oder andere buch wusste keine hilfe. deswegen frage ich jetzt hier in der hoffnung auf einen tip oder eine erklärung, warum es nicht funktioniert

    soweit so gut. mein ansatz sieht wie folgt aus:

    eine html-seite. wie auch immer aus dem zusammenhang gerissen, den css-code der einfachheit halber in den tags:
    Code:
    <!--das hier soll das eigentliche, recht statische menü sein-->
    <div id="menue" style="border:1px solid #000000;">
    <divonMouseOver="javascript:popup('menue_exp', 100, 100);">text</div>
    <div>several</div>
    <div>other</div>
    <div>menue</div>
    <div>items</div>
    </div>
    
    <!-- das hier soll das aufzuklappende menü sein-->
    <div id="menue_exp" style="display:none; position:absolute; top:20px; left20px;" onMouseOut="window.document.getElementById('menue_exp').style.display = 'none';">
    <div>several</div>
    <div>other</div>
    <div>menue</div>
    <div>items</div>
    </div>
    in der dazugehörigen javascript-datei folgt dann folgendes:

    Code:
    function increaseSize(menueID, currentHeight, currentWidth)
    {
    	window.document.getElementById(menueID).style.clip = "rect(0px, 0px, " + currentHeight + "px, " + currentWidth + "px)";
    }
    
    function popup(menueID, maxHeight, maxWidth)
    {
    	var currentHeight = 0;
    	var currentWidth = 0;
    	
    // am anfang wird das fenster gar nicht angezeigt. also komplett abgeschnitten
    	window.document.getElementById(menueID).style.clip = 'rect(0px, 0px, ' + currentHeight + 'px, ' + currentWidth + 'px)';
    	window.document.getElementById(menueID).style.display = 'block';
    
    // jetzt wird die anzeigebreite (clip) schrittweise erhöht, bis das maximum (maxHeight und maxWidth) erreicht sind
    	while(currentHeight < maxHeight || currentWidth < maxWidth)
    	{
    		if(currentHeight < maxHeight) currentHeight++;
    		if(currentWidth < maxWidth) currentWidth++;
    // da das ganze zu schnell abläuft, als dass man es sehen könnte wird der ablauf mit setTimeout verzögert
    		window.setTimeout("increaseSize(menueID, currentHeight, currentWidth)", 300);
    	}
    }
    -- erstes problem --

    das problem ist folgendes: obwohl als globale variable definiert, meldet javascript, dass in der zeile von setTimeout menueID, currentWidth und currentHeight nicht definiert wären. die divbox wird nicht geöffnet...
    laut diverser studien über gültigkeitsbereiche in JS sollte da aber kein problem sein !!??!!??

    baue ich vor das setTimeout ein alert(currentWidth) ein und begrenze die while-schleife auf 3 durchläufe mittels while(currentHeight < 2), so passiert interessanterweise folgendes:

    1.) es werden 4 (!!!) alert-boxen geöffnet, und zwar ZWEIMAL mit wert 0, einmal mit 1 und einmal mit 2... warum??? die divbox gleitet trotzdem nicht auf...
    2.) setze ich die anfangswerte für current**** auf 10, so wird die ERSTE veränderung der anzeige dargestellt, alle weiteren nicht!! warum????
    3.) übernehme ich die durch die funktion increaseSize() vorgenommene styleänderung in die funktion popup() (anstelle der setTimeout-geschichte), so wird die divbox ohne verzögerung geöffnet. aus eine verzögerung mittels leerer for-schleife bringt nichts
    4.) scheinen die schleifendurchläufe parallel verarbeitet zu werden? (threads?) kann ich mir zwar nicht vorstellen, aber...
    5.) ich habe auch schon versucht, nur in zwei schritten aufzuklappen, also OHNE while-schleife und mit verbose-ausgabe mittels alert(). leider klappte das auch nicht, da die erste änderng der anzeigeweite zwar übernommen wurde, die anderen aber nicht. die ausgegebenen vars waren aber korrekt gesetzt. interessanterweise wurde die erneut gesetzte anzeigeweite korrekt dargestellt, wenn ich das fenster minimiert und wieder geöffnet habe.


    wie bringe ich das script dazu, langsam aufzugleiten, wobei "langsam" klar definierbar ist (zB über eine variable)???
    (mit rekursion hab ichs inzwischen auch shcon probiert...)



    -- zweites problem --

    ist die divbox einmal geöffnet (also gesetzt den fall, ich lasse das aufgleiten weg um das erste problem zu umgehen) und ich öffne die aufzuklappende divbox und fahre mit dem mauszeiger darüber, dann klappt die divbox wieder zu, wenn ich das in der aufgeklappten div-box in ein anderes div (oder auch span) element komme. wie kann ich angeben, dass das fenster solange geöffnet bleibt, bis ich aus der "äusseren" div-box heraus bin?


    PS: browser: IE6 und FF1.5
    PPS: danke für alle antworten!!!!!

  2. #2
    ein schlauer ist offline Lounge-Member
    registriert
    18-08-2004
    Beiträge
    14.671

    AW: javascript: menüs aufgleiten lassen?

    Ich pick mal nur 2 Fehler raus.

    1. die Variabeln sind nicht global.
    PHP-Code:
    function popup(menueIDmaxHeightmaxWidth)
    {
        var 
    currentHeight 0;
        var 
    currentWidth 0;
    ... 
    Durch var stehen sie nur in der Funktion zu Verfügung.

    2. setTimeout, setzt (wie der Name schon andeutet) eine Zeitverzögerung, warten aber nicht, d.h. deine Schleife setzt x-Timeouts, die alle 300 Millisekunden später aufgrufen werden.

    Hier schwirren momentan mehrere Threads rum in denen erklärt wird wie's richtig geht.

  3. #3
    Xenon ist offline Jungspund
    registriert
    23-11-2005
    Beiträge
    11

    Unhappy AW: javascript: menüs aufgleiten lassen?

    hi!

    warum sollten die vars denn global sein ??? ich meine sie gelten doch in der gesamten funktion popup() und an die funktion increaseSize() übergebe ich sie explizit...
    hat javascript da ein anderes konzept in sachen gültigkeitsbereich für variablen als c oder java???
    soweit ich weiss ist das doch weitgehend gleich - abgesehen davon, dass vars in der gesamten funtion gelten...

    beim aufruf von increaseSize() müssten sie ja also auch definiert sein!? warum sollte ich sie global definieren?

    und was hat das schlüsselwort "var" damit zu tun? soweit ich meinem buch entnehmen kann, definiert var eine variable nu explizit, wärend sie ohne var implizit erzeugt wird...?


    dass setTimeout die ausführung der funktion um x ms verzögert ist mir klar. nur scheint es keine funktion in JS zu geben, die die ausführung EXPLIZIT für x ms anhält.
    welche funktion käme denn da in frage??


    allgemein: ich hab etwas im forum rumgesucht (und nicht nur in diesem!!) aber keine antwort auf die frage finden können, woran es denn liegt, dass das teil nicht aufgleitet, ja sich ncihtmal korrekt darstellen lässt...

  4. #4
    ein schlauer ist offline Lounge-Member
    registriert
    18-08-2004
    Beiträge
    14.671

    AW: javascript: menüs aufgleiten lassen?

    Das Schlüsselwort var definiert innerhalb einer Funktion eine Variabel lokal, d.h. sie ist nur noch innerhalb der Funktion sichtbar.
    In dem Aufruf window.setTimetout(' ') ist diese lokale Variabel als Parameter deklariert, da der Aufruf dieser Funktion aber im Kontext von window erfolgt (also quasi im gloabeln Kontext) ist diese Variabel nicht mehr sichtbar.

    dein setTimeout Problem wurde schon dutzende Male hier und anderswo durchgekaut.

    Du musst mit dem Timeout eine Funktion aufrufen, die sich dann mit einem Timeout wieder selbst aufruft, bis die abbruchbedingungen erfüllt sind.

  5. #5
    Xenon ist offline Jungspund
    registriert
    23-11-2005
    Beiträge
    11

    Arrow AW: javascript: menüs aufgleiten lassen?

    hi!

    danke für die erklärung! hab das mal ausprobiert und eine seite zusammengestrickt, die da austesten soll.

    leider klappt es immer noch nicht

    interessanterweise passiert folgendes: die funktion ruft sich mittels setTimeout() rekursiv selbst auf und zwar solange, bis die werte currentHeight und Width 200 erreicht haben. da die "current" werte bei 0 starten, sollten also 201 durchläufe erfolgen.
    das speichere ich alles in einer variable und gebe es dann mittels alert() aus, wobei interessanterweise herauskommt, dass statt 201 durchläufen nur 4 stattfinden !!!!!!!!?????????? (frage 1: warum ???)
    trotzdem hat das menu am ende nicht die werte style.display = rect(0,0,4,4), sondern die volle anzeigebreite. (frage 2: warum???)...

    ich kenne mich zwar mit diversen programmiersprachen aus (java/c/c++/php/haskell/prolog), aber SO ein verhalten ist mir noch nicht unergekommen
    javaSCRIPTtechnisch bin ich leider noch blutiger anfänger deswegen verzeih(t) mir bitte die dumme frage: WTF ist da los?
    an setTimeout() selber lisgts ja wohl eher nicht, da diese die funktion slideOpen() korrekt aufruft... nur leider nur 4 mal



    hier das javascript nochmal in seiner jetztigen form. der komplette code inkl. html und css findet sich im anhang...

    Code:
    var openMenus = new Array();
    var menuID;
    var currentHeight;
    var currentWidth;
    var maxHeight;
    var maxWidth;
    var timer = 0;
    var timer;
    var msg="";
    
    function closeOpenMenus()
    {
    	while(menuID = openMenus.pop())
    	{
    		window.document.getElementById(menuID).style.display = "none";
    	}
    }
    
    function openMenu(menuID)
    {
    	// first of all, we have to close all open menus
    	closeOpenMenus();
    	
    	// register new menu
    	openMenus.push(menuID);
    	
    	window.document.getElementById(menuID).style.display = "rect(0, 0, " + currentHeight + ", " + currentWidth + ")";
    	window.document.getElementById(menuID).style.display = "block";
    	slideOpen(menuID, 0, 0, 200, 200);
    }
    
    function slideOpen(menuID, currentHeight, currentWidth, maxHeight, maxWidth)
    {
    	if(currentHeight < maxHeight || currentWidth < maxWidth)
    	{
    		// this is for testing purposes
    		timer++;
    		msg += "currentHeight & Width: " + currentHeight + ", " + currentWidth + "\n";
    		
    		// increase the width and height to set
    		currentHeight++;
    		currentWidth++;
    		
    		// apply new width and height values
    		window.document.getElementById(menuID).style.display = "rect(0, 0, " + currentHeight + ", " + currentWidth + ")";
    		
    		// recursive call of slideOpen()
    		timer = setTimeout("slideOpen('" + menuID + "', '" + currentHeight + "', '" + currentWidth + "', '" + maxHeight + "', '" + maxWidth + "');", 0);
    	}
    	else
    	{
    		// output verbose
    		alert(timer + " calls of slideOpen()\n----------\n" + msg);
    		return true;
    	}
    }
    schonmal ein grosses dankeschön an alle antwortenden!!
    Angehängte Dateien Angehängte Dateien

  6. #6
    ein schlauer ist offline Lounge-Member
    registriert
    18-08-2004
    Beiträge
    14.671

    AW: javascript: menüs aufgleiten lassen?

    Da ich gerade nur an einem Uralt Rechner sitze kann ich das nicht ausprobieren, aber evtl. liegt das ganze daran, dass du den Timeout auf 0 gesetzt hast, dann werden die Aufrufe wohl auch fast Zeitgleich aufgerufen. Du kannst das verhindern in dem du entweder den Interval auf einen höheren Wert setzt (solche Bewegungen sind relativ Zeitintensiv und unter 50-60 ms wäre das ganze auch unrealistisch da die Bewegung dann schneller als das menschliche Auge wäre, nur so schnell ist momentan kein Browser) oder du setzt einen Flag, um zu kennzeichnen das die Funktion abgearbeitet wird. So in der Art:

    var busy = false;

    function slideOpen(...)
    {
    if(busy) return;
    busy = true;
    ....

    busy = false;
    }

  7. #7
    Xenon ist offline Jungspund
    registriert
    23-11-2005
    Beiträge
    11

    Cool AW: javascript: menüs aufgleiten lassen?

    hi!

    danke erstmal für deine antwort! ich habe da jetzt nochmals einige stunden dran gearbeitet (will sagen: probiert und festgestellt, dass ich schon fast 2 tage dransitze ) und bin auf folgendes gekommen:

    a) die rekursion brach ab, da ich die werte nicht als integer übergeben habe, sondern in ' '. damit ist '3' > '200'... ich weiss, warum ich strikte typisierung vorziehe!!!

    b) was ich bislang nur an einer stelle gefunden habe ist die JS-notation für rect(). und zwar liest die sich
    Code:
    document.elementID.style.clip = "rect(a + "px, " + b + "px, " + c + "px, " + d + "px)";

    da hören die probleme aber leider nicht auf
    diverse tutorials sagen zwar, dass es damit getan wäre, aber: NIX IST

    de facto passiert folgendes: die box klappt auf, aber NICHT SICHTBAR! interessanterweise kann man das browserfenster minimieren und wieder maximieren (oder vorübergehend einfach ein anderes in den vordergrund holen) und siehe da: DANN (und nur dann) wird die div-box angezeigt. man kann auch deutlich sehen, dass sie wie gewollt aufklappt, wenn man schnell ist.
    nur ANIMATION kann man das nicht nennen.
    style.display = 'block' oder style.visibility = 'visible' nach jedem funktionsaufruf bringen leider gar nix.

    aber das ist nur problem nummer 1...
    nummer 2 wäre: lässt man die box (unsichtbar) aufklappen, minimiert das browserfenster und maximiert es anschliessend wieder (damit die aufgeklappte divbox auch angezeigt wird), so kann man nxi damit anfangen.
    die divbox wirkt wie ein "nichtmaterieller" layer über der website: man kann keine links anklicken und keinen text markieren, um nur 2 beispiele zu nennen...

    wie bringe ich JS bzw den browser dazu, JEDE änderung der css-styles auch SOFORT grafisch umzusetzen? (und auch so, dass das html "nutzbar" ist)?


    PLEASE HELP!!!


    PS:
    busy kann doch gar nicht klappen, da im fall, dass busy == true sämtliche weitere abarbeitung abgebrochen wird!?

    PPS:
    das "neue" script auch nochmal im anang:

    Code:
    var openMenus = new Array();
    var menuID;
    var currentHeight;
    var currentWidth;
    var maxHeight;
    var maxWidth;
    var timer;
    var slider;
    
    function closeOpenMenus()
    {
    	while(menuID = openMenus.pop())
    	{
    		window.document.getElementById(menuID).style.display = "none";
    	}
    }
    
    function openMenu(menuID)
    {
    	// first of all, we have to close all open menus
    	closeOpenMenus();
    	
    	// register new menu
    	openMenus.push(menuID);
    	
    	window.document.getElementById(menuID).style.clip = "rect(0px, 0px, " + currentHeight + "px, " + currentWidth + "px);";
    	window.document.getElementById(menuID).style.display = "block";
    	slideOpen(menuID, 0, 0, 200, 200);
    }
    
    function slideOpen(menuID, currentHeight, currentWidth, maxHeight, maxWidth)
    {
    	if(currentHeight <= maxHeight || currentWidth <= maxWidth)
    	{
    		// increase the width and height to set
    		currentHeight++;
    		currentWidth++;
    		
    		// apply new width and height values
    		window.document.getElementById(menuID).style.clip = "rect(0px, 0px, " + currentHeight + "px, " + currentWidth + "px);";
    		window.document.getElementById(menuID).style.display = "block";
    		
    		// recursive call of slideOpen()
    		timer = setTimeout("slideOpen('" + menuID + "', " + currentHeight + ", " + currentWidth + ", " + maxHeight + ", " + maxWidth + ");", 0);
    	}
    	else
    	{
    		return true;
    	}
    }
    Geändert von Xenon (23-11-2005 um 18:06 Uhr)

  8. #8
    ein schlauer ist offline Lounge-Member
    registriert
    18-08-2004
    Beiträge
    14.671

    AW: javascript: menüs aufgleiten lassen?

    Das mit busy war nicht ganz überlegt, aber das dürfte erstmal nicht das Problem sein. (du benutzt nach wie vor 0 Millisekunden als Verzögerung das kann u.U. kritisch sein zumal dein window.setTimout() Aufruf nicht am Ende der Funktion kommt.)

    So wie du es beschreibst sind das eher CSS Probleme die sich irgendwie in die Quere kommen. Kannst du das ganze auf ein lauffähiges Beispiel reduzieren und online stellen, weil so läßt sich nur raten was falsch läuft. Denn hier im Forum klappt das ja.

  9. #9
    Xenon ist offline Jungspund
    registriert
    23-11-2005
    Beiträge
    11

    Cool AW: javascript: menüs aufgleiten lassen?

    hi there!

    ich hab das ganze mal online gestellt. zu finden auf http://www.3rd-level.org/xenon/css/test.html

    zur setTimeout():
    ich hab schon diverse zeitangaben durchprobiert... bringen tut es leider nix auch treten besagte probleme sowohl im IE als auch im FF auf

    der setTimeout()-aufruf steht doch am ende der funktion - danach kommt nur noch der else-zweig: also ist setTimeout() - SOFERN aufgerufen - die letzte anweisung der funktion slideOpen(), die ausgeführt wird. (wenn der sprung in den else-zweig kommt, wird setTimeout() ja gar nicht aufgerufen...)

    parallele ausführung der funktion slideOpen() o.ä. sollte also nicht passieren...

    trotzdem tuts das nicht


    ich hab jetzt mal eine seperate funktion eingebaut, die mittels setInterval die grösse hin- und herspringen lässt...
    das interval wird zwar immer aufgerufen, aber die änderungen sind NICHT sichtbar...
    weiss der geier warum

    PS: das hin und herspringen der werte klappt auch... (link partToggleOpen() anklicken und dann directOpen())
    das direkte anzeigen der änderung klappt aber genausowenig wie beim setTimeout()
    Geändert von Xenon (23-11-2005 um 21:23 Uhr)

  10. #10
    ein schlauer ist offline Lounge-Member
    registriert
    18-08-2004
    Beiträge
    14.671

    AW: javascript: menüs aufgleiten lassen?

    deine clip Werte sind falsch.

    Ein kurzer Blick in den Quellcode vom Slidemenu hier vom Board, führt zu dem Ergebnis:
    PHP-Code:
            // apply new width and height values
            
    window.document.getElementById(menuID).style.clip 
            
    "rect(auto, " currentHeight "px, " currentWidth "px, auto);"

  11. #11
    Xenon ist offline Jungspund
    registriert
    23-11-2005
    Beiträge
    11

    Thumbs up AW: javascript: menüs aufgleiten lassen?

    oh mann... ich glaube es nicht...
    das hatte ich zwar auch shcon gesehen, aber da es ohne timeout in die richtige richtung öffnete, hab ich mir nix dabei gedacht...
    ES KLAPPT wahnsinn!!!

    an dieser stelle ein WAHNSINNIG GROSSES DANKESCHÖN an dich für deine geduld und hilfe !!!!!!!!!!!!!!!

    ich hoffe, ich kann mich irgendwann mal revanchieren...

Ähnliche Themen

  1. Javascript durch Link auf 2. Seite ausführen??
    Von Bass-T im Forum JavaScript
    Antworten: 4
    Letzter Beitrag: 27-06-2008, 11:35
  2. Was ist JavaScript?
    Von .holger im Forum JavaScript-FAQ
    Antworten: 4
    Letzter Beitrag: 27-11-2006, 10:00
  3. hilfe bei javascript
    Von frank2000 im Forum JavaScript
    Antworten: 0
    Letzter Beitrag: 17-01-2005, 19:33
  4. Attribut in XSL-Tag mittels JavaScript ändern???
    Von Phelagor im Forum JavaScript
    Antworten: 4
    Letzter Beitrag: 01-09-2003, 02:01
  5. window.popup aus flash
    Von antiheld2000 im Forum Flash
    Antworten: 6
    Letzter Beitrag: 18-07-2003, 14:26

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •