sho: dynamische Liste aus Arrays

Hallo zusammen,

ich versuche folgendes:
1. per onclick eine Liste erstellen, die aus einem Array generiert wird
2. wenn das Array an der Position [i] ein weiteres Array enthält, aus dem eine neue Liste erzeugt werden sollte, dann
3. soll beim erzeugen von 1. schon ein Linktag in dem Listenpunkt erzeugt werden, damit dann
4. beim Klick darauf die "alte" Liste wieder entfernt und die neue mit 1. erzeugt werden kann

Bisher funktioniert 1. :-) Bei 2. Hakt es am Verständnis von JS-Arrays. Wie bekomme ich hin, dass mein array level2 mit level1[0] assoziiert wird ohne den Inhalt zu überschreiben? 3. und 4. lasse ich erstmal außen vor, sonst wirds viell. zu umständlich. Hier mal der Code - ich hoffe das Vorhaben ist verständlich?!..

  
<!DOCTYPE html">  
  
<html>  
    <head>  
        <meta charset="utf-8">  
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">  
        <meta name="description" content="">  
  		<meta name="author" content="">  
        <meta name="viewport" content="width=device-width, initial-scale=1.0">  
  
   <title>Navigation "neu laden"</title>  
   <style type ="text/css">  
	<!--  
	html, body{  
		font-family:Arial, sans serif;  
		font-size:14px;  
		}  
		.clear{  
		clear:both;  
		}  
		a{  
		text-decoration:none;  
		}  
		ul#submenu{  
		list-style:none;  
		width:18em;  
		height:10em;  
		margin:0;  
		padding:0;  
		background:red;  
		}  
		ul#submenu li{  
		display:block;  
		border:1px solid black;  
		border-radius:5px;  
		margin:2px;  
		width:4em;  
		height:2em;  
		float:left;  
		}  
	-->  
	</style>  
	<script type="text/javascript">  
	var level1=new Array("lev1-1","lev1-2","lev1-3","lev1-4","lev1-5","lev1-6");  
	var level2=new Array("lev2-1","lev2-2","lev2-3","lev2-4","lev2-5","lev2-6","lev2-7","lev2-8","lev2-9");  
	//level1[0]=new Array("lev2-1","lev2-2","lev2-3","lev2-4","lev2-5","lev2-6","lev2-7","lev2-8","lev2-9");  
	//var level3=level1[0].concat(level2);  
			  
	function generateNewList(node){  
	//Aktuelle Kategorie anzeigen, von der man gekommen ist  
	var shownLevel = node.firstChild.nodeValue;  
	var beginText = 0;  
	var lengthOfText = document.getElementById("shownLevel").firstChild.nodeValue.length;  
					document.getElementById("shownLevel").firstChild.replaceData(beginText, lengthOfText, shownLevel);  
	for (var i = 0; i < level1.length; i++) {  
	 var newLi = document.createElement("li");  
	 var newLiText = document.createTextNode(level1[i]);  
	 document.getElementById("submenu").appendChild(newLi);  
	 document.getElementsByTagName("li")[i].appendChild(newLiText);  
	//PSEUDO  
	if(level2.length>0){  
	/*wenn level2 (eigentlich level1[0]) .length>0, dann in dem erstellten LI einen Anker erstellen appendChild("a"),  
	der dann wiederum onclick generateNewList aufruft, um eine Liste aus Array Level2 in ul.submenü zu erstellen.*/  
	}  
	}  
	}					  
     </script>  
    </head>  
    <body>  
		<header>  
			-----kopf-----  
		</header>  
		<h2><a id="shownLevel" onclick="generateNewList(this)">Test: generiere Liste</a></h2>  
			<ul id="submenu">  	  	  
			  
				<!--dynamic list menu-->		  
			</ul>  
			<div class="clear"></div>  
		<footer>  
			-----fuhu&szlig;-----  
		</footer>  
    </body>  
    </html>  

Freu mich über Hinweise
Frohe Pfingsten

  1. Hallo,
    Ich würde da vom objekt-orientierten Standpunkt her herangehen:
    Was ist ein Menu?
    Ein Menu-Element bestehe aus

    • einem Titel
    • (optional) einer Liste von Untermenus
      
    function MyMenu(title) {  
       this.title = title;  
       this.items = new Array();  
    }  
    MyMenu.proptotype.addItem = function (item) {  
       this.items.push(item);  
    }  
      
    // Build a little Menu  
    var menu = new MyMenu("Testmenu");  
    var untermenu = new MyMenu ("Untermenu");  
    menu.addItem(untermenu);  
    untermenu.addItem(new MyMenu("Unteroption1"));  
    untermenu.addItem(new MyMenu("Unteroption2"));  
      
    // Traversing Menu  
    for (var i = 0; i< menu.items.length; i++) {  
       var untermenu = menu.items[i];  
       if (untermenu.items.length > 0) {  
          // weitere untermenus  
       }  
       else {  
         // keine untermenus  
       }  
    }  
    
    

    Bei komplexeren Menustrukturen wird das Aufbauen wie unter "Build a little Menu" beschrieben ggf. etwas umständlich.
    Du solltest daher vielleicht den "MyMenu"-Konstruktor so bauen, dass Du ihm einfach JSON-Daten übergeben kannst:

      
    function MyMenu(jsonObj) {  
       if (typeof(jsonObj.title) == "undefined") {  
          // every menu needs at least a title  
          throw "This seams to be not a valid menu";  
       }  
       this.title = jsobObj.title;  
       this.items = new Array();  
       if ((typeof(jsonObj.items) != "undefined") && (jsonObj.items.length)) {  
          for (var i = 0; i < jsobObj.items.length; i++) {  
             this.items.push(new MyMenu(jsonObj.items[i]));  
          }  
       }  
      
    }  
      
    
    

    // And here we go:
    var menu = new MyMenu ({'title' : 'Testmenu', items : [{'title' : 'untermenu', items : [...]}]});

    Hoffe es sind nicht so viele Tippfehler drin, und es hilft Dir weiter.

    Viele Grüße,
    Jörg

    1. Hallo Jörg, erst einmal Vielen Dank für deine schnelle Antwort. Tatsächlich werd ich bei den JSON objekten landen müssen, soweit bin ich jedoch nicht :-) Ich habe versucht, die Objekt-Variante anzuwenden, damit ich auch verstehe was ich tue:

        
      <!DOCTYPE html">  
        
      <html>  
          <head>  
              <title>Navigation "neu laden"</title>  
      		<style type ="text/css">  
      		<!--  
      			html, body{  
      				font-family:Arial, sans serif;  
      				font-size:14px;  
      			}  
      			.clear{  
      				clear:both;  
      			}  
      			a{  
      			text-decoration:none;  
      			}  
      			ul#submenu{  
      				list-style:none;  
      				width:18em;  
      				height:10em;  
      				margin:0;  
      				padding:0;  
      				background:red;  
      			}  
      			ul#submenu li{  
      				display:block;  
      				border:1px solid black;  
      				border-radius:5px;  
      				margin:2px;  
      				width:4em;  
      				height:2em;  
      				float:left;  
      			}  
      		-->  
      		</style>  
      		<script type="text/javascript" src="jquery.js"></script>  
      		<script type="text/javascript">  
      			function MyMenu(title, items) {  
      			this.title = title;  
      			this.items = new Array();  
      			  
      			MyMenu.prototype.addItem = function (item) {  
      			   this.items.push(item);  
      			}  
      			}  
      			function machMenu(){  
      	  
      			var menu = new MyMenu("Testmenu");  
      			var untermenu = new MyMenu ("Untermenu");  
      			//hier wird dem Testmenu das Untermenu hinzugefügt  
      			menu.addItem(untermenu);  
      			//hier bekommt das Untermenu zwei neue Untermenupunkte  
      			untermenu.addItem(new MyMenu("Unteroption1"));  
      			untermenu.addItem(new MyMenu("Unteroption2"));  
        
      			// Traversing Menu  
      			for (var i = 0; i< menu.items.length; i++) {  
      //warum wieder var untermenu??  
      			   var untermenu = menu.items[i];  
      			   alert (untermenu.length);  
      			   if (untermenu.length > 0) {  
      				  // weitere untermenus  
      			   }  
      			   else {  
      				 // keine untermenus  
      				 alert ("keine");  
      			   }  
      			}		  
      			}  
      		  
      		</script>  
          </head>  
          <body onload="machMenu()">  
      		<header>  
      			-----kopf-----  
      		</header>  
      		<h2><a id="shownLevel">Test: generiere Liste</a></h2>  
      	  
      			<ul id="submenu">  	  	  
      			  
      				<!--dynamic list menu-->		  
      			</ul>  
      			<div class="clear"></div>  
      		<footer>  
      			-----fuhu&szlig;-----  
      		</footer>  
          </body>  
          </html>  
      
      

      Ehrlich gesagt verstehe ich nicht, warum das untermenu per alert keine "länge" hat, es müsste doch 2 Einträge haben. Hab ich das falsch eingebaut?

      Viele Grüße

      1. ok..also ich generiere jetzt (hoffentlich korrekt) mein submenu (siehe code unten :-)) danke noch mal für die objekterhellung.

        ABER ich brauche noch HILFE für:

        • wenn mein untermenu auch unterpunkte enthält, (was es ja tut (untermenu2), dann soll das nicht automatisch hinzugefügt werden, sondern der entsprechende Listenpunkt soll ja einen Link erhalten. Und wenn man diesen dann klickt soll die funktion machMenu erneut aufgerufen werden, die aktuellen Listenpunkte gelöscht und die nächste Unterebene generiert. Kann mir dabei noch jmd helfen?
          
        <!DOCTYPE html">  
          
        <html>  
            <head>  
                <title>Navigation "neu laden"</title>  
        		<style type ="text/css">  
        		<!--  
        			html, body{  
        				font-family:Arial, sans serif;  
        				font-size:14px;  
        			}  
        			.clear{  
        				clear:both;  
        			}  
        			a{  
        			text-decoration:none;  
        			}  
        			ul#submenu{  
        				list-style:none;  
        				width:18em;  
        				height:10em;  
        				margin:0;  
        				padding:0;  
        				background:red;  
        			}  
        			ul#submenu li{  
        				display:block;  
        				border:1px solid black;  
        				border-radius:5px;  
        				margin:2px;  
        				width:12em;  
        				height:2em;  
        				float:left;  
        			}  
        		-->  
        		</style>  
        		<script type="text/javascript" src="jquery.js"></script>  
        		<script type="text/javascript">  
        			//Konstruktor für Menüobjekte  
        			function MyMenu(title, items) {  
        				this.title = title;  
        				this.items = new Array();  
        				  
        				MyMenu.prototype.addItem = function (item) {  
        				   this.items.push(item);  
        				}  
        			}  
        			//Menü erstellen  
        			function machMenu(){  
        			/*function deleteActSubmenu(){  
        				$('#submenu li').remove();  
        			}*/	  
        			var menu = new MyMenu("Testmenu");  
        			var untermenu1 = new MyMenu ("Untermenu1");  
        			var untermenu2 = new MyMenu ("Untermenu2");  
        			//hier wird dem Testmenu das Untermenu hinzugefügt  
        			menu.addItem(untermenu1);  
        			menu.addItem(untermenu2);  
        			//hier bekommt das Untermenu zwei neue Untermenupunkte  
        			untermenu1.addItem(new MyMenu("Untermenu1-1"));  
        			untermenu1.addItem(new MyMenu("Untermenu1-2"));  
          
        			untermenu2.addItem(new MyMenu("Untermenu2-1"));  
        			untermenu2.addItem(new MyMenu("Untermenu2-2"));  
        			untermenu2.addItem(new MyMenu("Untermenu2-3"));  
        			untermenu2.addItem(new MyMenu("Untermenu2-4"));  
        			  
        			// Traversing Menu  
        			for (var i = 0; i< menu.items.length; i++) {  
        			   var untermenu = menu.items[i].items;  
        			   if (untermenu.length > 0) {  
        					for (var i=0;i<untermenu.length;i++){  
        						var newLi = document.createElement("li");  
        						document.getElementById('submenu').appendChild(newLi);  
        						var newLiText = document.createTextNode(menu.items[i].title);  
        						document.getElementsByTagName('li')[i].appendChild(newLiText);  
        					}  
        			   }  
        			   else {  
        				 // keine untermenus  
        				 alert ("keine");  
        			   }  
        			}		  
        			}  
        		  
        		</script>  
            </head>  
            <body>  
        		<header>  
        			-----kopf-----  
        		</header>  
        		<h2><a id="shownLevel" href="javascript:machMenu()">Test: generiere Liste</a></h2>  
        	  
        			<ul id="submenu">  	  	  
        			  
        				<!--dynamic list menu-->		  
        			</ul>  
        			<div class="clear"></div>  
        		<footer>  
        			-----fuhu&szlig;-----  
        		</footer>  
            </body>  
            </html>  
        
        
      2. Hallo,

        Ehrlich gesagt verstehe ich nicht, warum das untermenu per alert keine "länge" hat, es müsste doch 2 Einträge haben.

        Nein. Das "untermenu" ist gleichgesetzt mit "menu.items[i]".
        menu.items[i] ist aber seinerseits wieder ein Objekt vom Typ "MyMenu", das besitzt keine Länge. "untermenu.length" würde nur funktionieren, wenn "untermenu" ein Array wäre.

        alert (untermenu.items.length);

        hingegen müsste Dir die Länge "2" zurück geben, da Du damit auf das Array "items" INNERHALB des Objektes "untermenu" mit den  beiden Elementen "Unteroption1" und "Unteroption2" zugreifst.

        //warum wieder var untermenu??

        Das hätte ich vielleicht der Übersicht halber anders nennen sollen. Es sollte aber trotzdem funktionieren, da das zweite "var untermenu" in einem separaten Block steht, somit das erste "var untermenu" nicht überschreiben kann.

        Viele Grüße,
        Jörg