• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Drop Down-Menü mit Javasript

Sheva

Neues Mitglied
Hallo Leute,

vor ein paar Tagen habe ich mir ein Beispiel für ein Drop-Down-Menü mit javascript rausgesucht. Hab gleich dieses vorgefertigtes genommen:

Code:
/*
 * Fügt den Listeneinträgen Eventhandler und CSS Klassen hinzu,
 * um die Menüpunkte am Anfang zu schließen.
 *
 * menu: Referenz auf die Liste.
 * data: String, der die Nummern aufgeklappter Menüpunkte enthält.
 */
function treeMenu_init(menu, data) {
    var array = new Array(0);
    if(data != null && data != "") {
        array = data.match(/\d+/g);
    }
    var items = menu.getElementsByTagName("li");
    for(var i = 0; i < items.length; i++) {
        items[i].onclick = treeMenu_handleClick;
        if(!treeMenu_contains(treeMenu_getClasses(items[i]), "treeMenu_opened")
            && items[i].getElementsByTagName("ul").length
            + items[i].getElementsByTagName("ol").length > 0) {
            var classes = treeMenu_getClasses(items[i]);
            if(array.length > 0 && array[0] == i) {
                classes.push("treeMenu_opened")
            }
            else {
                classes.push("treeMenu_closed")
            }
            items[i].className = classes.join(" ");
            if(array.length > 0 && array[0] == i) {
                array.shift();
            }
        }
    }
}

/*
 * Ändert die Klasse eines angeclickten Listenelements, sodass
 * geöffnete Menüpunkte geschlossen und geschlossene geöffnet
 * werden.
 *
 * event: Das Event Objekt, dass der Browser übergibt.
 */
function treeMenu_handleClick(event) {
    if(event == null) { //Workaround für die fehlenden DOM Eigenschaften im IE
        event = window.event;
        event.currentTarget = event.srcElement;
        while(event.currentTarget.nodeName.toLowerCase() != "li") {
            event.currentTarget = event.currentTarget.parentNode;
        }
        event.cancelBubble = true;
    }
    else {
        event.stopPropagation();
    }
    var array = treeMenu_getClasses(event.currentTarget);
    for(var i = 0; i < array.length; i++) {
        if(array[i] == "treeMenu_closed") {
            array[i] = "treeMenu_opened";
        }
        else if(array[i] == "treeMenu_opened") {
            array[i] = "treeMenu_closed"
        }
    }
    event.currentTarget.className = array.join(" ");
}

/*
 * Gibt alle Klassen zurück, die einem HTML-Element zugeordnet sind.
 *
 * element: Das HTML-Element
 * return: Die zugeordneten Klassen.
 */
function treeMenu_getClasses(element) {
    if(element.className) {
        return element.className.match(/[^ \t\n\r]+/g);
    }
    else {
        return new Array(0);
    }
}

/*
 * Überprüft, ob ein Array ein bestimmtes Element enthält.
 *
 * array: Das Array
 * element: Das Element
 * return: true, wenn das Array das Element enthält.
 */
function treeMenu_contains(array, element) {
    for(var i = 0; i < array.length; i++) {
        if(array[i] == element) {
            return true;
        }
    }
    return false;
}

/*
 * Gibt einen String zurück, indem die Nummern aller geöffneten
 * Menüpunkte stehen.
 *
 * menu: Referenz auf die Liste
 * return: Der String
 */
function treeMenu_store(menu) {
    var result = new Array();;
    var items = menu.getElementsByTagName("li");
    for(var i = 0; i < items.length; i++) {
        if(treeMenu_contains(treeMenu_getClasses(items[i]), "treeMenu_opened")) {
            result.push(i);
        }
    }
    return result.join(" ");
}

Quelle: JavaScript: Aufklappbare Mens

Nun hat auch am Anfang alles wunderbar funktioniert. Hab die Fuktionen per onload in meinen body Tag geladen:

HTML:
<body onload="treeMenu_init(document.getElementById('links'), unescape(window.name).split(',')[0]);" onunload="window.name = escape(treeMenu_store(document.getElementById('links')));">

Nun brauch ich jedoch noch eine Funktion die mir die geöffneten Menüs wieder zuklappt wenn ich ein anderes aufmache.

Funktion war in dem Beispiel anscheinend gleich mit dabei:

Code:
/*
 * Ändert die Klasse eines angeclickten Listenelements, sodass
 * geöffnete Menüpunkte geschlossen und geschlossene geöffnet
 * werden.
 *
 * event: Das Event Objekt, dass der Browser übergibt.
 */
function treeMenu_handleClick(event) {
    if(event == null) { //Workaround für die fehlenden DOM Eigenschaften im IE
        event = window.event;
        event.currentTarget = event.srcElement;
        while(event.currentTarget.nodeName.toLowerCase() != "li") {
            event.currentTarget = event.currentTarget.parentNode;
        }
        event.cancelBubble = true;
    }
    else {
        event.stopPropagation();
    }
    var array = treeMenu_getClasses(event.currentTarget);
    for(var i = 0; i < array.length; i++) {
        if(array[i] == "treeMenu_closed") {
            array[i] = "treeMenu_opened";
        }
        else if(array[i] == "treeMenu_opened") {
            array[i] = "treeMenu_closed"
        }
    }
    event.currentTarget.className = array.join(" ");
}

Nun habe ich aber kein Plan wie ich diese einbinde. Theoretisch ja nur über "onclick=treeMenu_handleClick(event). Das Event ist ja dann "onclick" ?

Habe ich bereits versucht nur hat nicht geklappt. Auch mit

Code:
onunload="window.name = escape(treeMenu_store(document.getElementById(onclick)));

hat es nicht funktioniert.

Habt ihr ein Lösung parat ? Hätte das Menü auch gerne selbst geschrieben nur hab erst mit der Programmiersprache Javascript angefangen und aus Zeitgründen mir daher lieber ein vorgefertigtes aus dem Internet gesucht.

Wäre über jede Hilfe dankbar !
 
Habt ihr ein Lösung parat ? Hätte das Menü auch gerne selbst geschrieben nur hab erst mit der Programmiersprache Javascript angefangen und aus Zeitgründen mir daher lieber ein vorgefertigtes aus dem Internet gesucht.

Einen Ratschlag. Lerne erst einmal JS und kopiere niemals Code, den du (noch) nicht interpretieren kannst, um ihn anchließend irgendwie anzupassen. So etwas nennt man voodoo chicken coding. Das Beispiel von selfhtml ist sogar noch besonders umständlich und kompliziert. Wer käme schon auf den Gedanken, eine simple Navigation mit Regular Expressions zu bauen?

Du kannst so ein Menu ebenso gut mit CSS schreiben. Das geht viel einfacher und du lernst noch etwas dabei.
 
Zuletzt bearbeitet:
Copy and Paste macht überhaupt keinen Sinn sofern man den Code nicht versteht.

Sheva schrieb:
Jedoch nicht mit irgendwelchen click-Events ?!
Alles was möglich ist sollte mit CSS gemacht werden. Restliche Funktionalitäten werden über JS dann nachgerüstet.

Hier mal ein provisorisches Beispiel mit minimalem (Naja, jQuery ist halt dabei) Aufwand an JS.
http://pastie.org/5028948

~cookie
 
Zuletzt bearbeitet:
Copy and Paste macht überhaupt keinen Sinn sofern man den Code nicht versteht.


Alles was möglich ist sollte mit CSS gemacht werden. Restliche Funktionalitäten werden über JS dann nachgerüstet.

Hier mal ein provisorisches Beispiel mit minimalem (Naja, jQuery ist halt dabei) Aufwand an JS.
#5028948 - Pastie

~cookie

Sieht definitv einfacher aus als das von SELFHTML. Werd mir das mal durchlesen und es versuchen nachzuvollziehen. Danke erstmal für die schnelle Hilfe !
 
Hab das mit dem Menü jetzt mal auf einer anderen Seite probiert und funktioniert echt prima.

Allerdings klappt er das Menü bei meiner ersten Seite komplett auf bevor ich überhaupt was geklickt habe sodass es komplett offen ist wenn ich sie Seite aufmache.
firebug.JPG


Hier da mal ein Auszug aus Firebug.

Bei meiner zweiten Seite die ich gerade erstelle funktioniert es einwandfrei (auch da mal ein Screenshot)
firebug_sole.JPG


So und der einzige Grund warum er das Menü gleich ganz aufmacht und auflässt könnte doch nur der sein das im oberen Screenshot (1 Internetseite) bereits ein <ul> im untergeordneten <li> steht. Ist ja beim unteren (2 Internetseite) nicht so.

Ich hoffe es kommt einigermaßen verständlich rüber. Ich habe keine Ahnung warum es bei Seite 1 nicht funktioniert, dafür aber bei Seite 2.
 
Die Frage kann man so nicht beantworten. Wie sieht der von dir verwendete CSS-Code aus? Ideal wäre ein Link zur Webseite?
 
Das Menü funktioniert an sich prima nur fällt mir gerade auch beim CSS-Code auf das das so gar nicht möglich ist.

Denn wie man oben sieht kann ich den Obermenüs und Untermenüs keine id's zuordnen da das Menü ja mit joomla erstellt wurde. Es gibt im Joomla nur die Möglichkeit den einzelnen Menüpunkten Klassen zu geben, aber selbst dann gibt er die Klassen dann nur den <a> anstatt den <li>. Und die Menüpunkte über die item133 etc. anzusprechen ist auch nicht wiklich hilfreich da ja auch jederzeit neue Menüpunkte hinzukommen können und der Nutzer (in dem Fall der Kunde) das alleine regeln soll.
 
Nach nun einigen verschiedenen Versuchen später hätte ich noch eine Frage.

Ich habe das ganze mit dem Javascript Menü von dieser Seite hier gemacht:

#5028948 - Pastie

Wurde ja auch schon gepostet und ist vom Umfang sowie auch von der Verständlichkeit her leichter. Meine angepasste Funktion sieht so aus:

HTML:
    <script type="text/javascript">
        $(function(){

            $('ul.joomla-nav > li').click(function(){ 
                $('ul.joomla-nav > li ul').stop().slideUp('fast'); 
                $(this).find('ul').stop().slideDown('fast'); 
            });

            $(document).mouseup(function (e){ 
                var sel = $('ul.joomla-nav'); 
                if (!sel.is(e.target) && sel.has(e.target).length === 0){ 
                    $('ul.joomla-nav > li ul').stop().slideUp('fast'); 
                }
            });
        });
    </script>

In der 5 Zeile von unten wird ja soweit ich das richtig verstehe der aktuelle Status des Menüs gespeichert, sodass ich, wenn ich auf einen Menüpunkt klicke das Menü geöffnet bleibt.
Allerdings scheint er das bei mir noch nicht zu speichern. Die Funktion steht in keiner separaten js-datei. Hab Sie in die index.php eingefügt.
 
In der 5 Zeile von unten wird ja soweit ich das richtig verstehe der aktuelle Status des Menüs gespeichert, sodass ich, wenn ich auf einen Menüpunkt klicke das Menü geöffnet bleibt.
Allerdings scheint er das bei mir noch nicht zu speichern. Die Funktion steht in keiner separaten js-datei. Hab Sie in die index.php eingefügt.


Die von dir besagte Zeile speichert lediglich eine Instanz der Navigation und nicht den Status. Das dient lediglich zur Vereinfachung des Zugriffs auf diese Instanz.

Der folgende Code lässt die Navigation einfach einklappen sobald man außerhalb der Navi irgendwohin klickt.
 
Der folgende Code lässt die Navigation einfach einklappen sobald man außerhalb der Navi irgendwohin klickt.

Wobei diese Schreibweise bei mir auch zwei Fragen aufwirft.
Code:
$(document).mouseup(function (e){ 
  var sel = $('ul#navi');
  if (!sel.is(e.target) && sel.has(e.target).length === 0){ 
     $('ul#navi > li ul').stop().slideUp('fast');
  }        
});

- Ich hätte hier click() verwendet. Warum nimmst du statt dessen ein mouseup()? Es funktioniert übrigens Beides.

- event.targent steht für this und demzufolge checkt der erste Teil der Abfrage (!sel.is(e.target)), ob der User außerhalb der Navigation klickt. Aber was genau macht sel.has(e.target).length === 0) hier? Die Bedingung e.length === 0 steht doch dafür, dass ein Element nicht existiert, oder?
 
Zurück
Oben