*.appendChild(irgendwas); geht nicht

NetBull

Erfahrenes Mitglied
Hi,

ich versuche mich an einem TreeView, ... die erste ebene klappt. Danach verschachtelt JavaScript mir die Tags so das beim Klick auf Childs auch die clickEvents der parents ausgeführt werden.

das bauen der Nodes:
Code:
function loadtreeView(aParentNode)
	{
		var isEmpty = false;
		var i=0;
		var mParentNodeId = 0;
		
		var mParendNode = document.getElementById(null);
		mParendNode = aParentNode;		
		if(aParentNode!=null)
			mParentNodeId = aParentNode.getAttribute("dbid");
		
		do
		{		
			initiateAjaxRequest("getNodes", i, -1, mParentNodeId, false);
			var xmlResponse = new xmlResponseObject();
			if( !xmlResponse.isEmpty()  &&  !xmlResponse.isError() )
			{	
				xmlDataSet = xmlResponse.getNextData();				
				loadTreeViewItem(aParentNode, xmlDataSet[0]);
			}
			else
				isEmpty=true;
			i++;
		}while(!isEmpty);
	}

function loadTreeViewItem(aParentNode, aTvDataSet)
	{	
		var treeViewParent = document.getElementById(null);
		treeViewParent = aParentNode;
		if(treeViewParent==null)
		{
			treeViewParent = document.getElementById("treeViewObject");
			treeViewParent.setAttribute("dbid", 0, 0);
		}
		
		var mNodeIcon = "tvnUnknown.png";
		var mSwitchVar = parseInt(aTvDataSet['type']);
		
		var mHasChilds=false;
		if(parseInt(aTvDataSet['numberOfChilds']>0))
			mHasChilds=true;

		switch(mSwitchVar)
		{
			case 1:
				mNodeIcon = "tvnCompany.png";
				break;
			case 2:
				mNodeIcon = "tvnPerson.png";
				break;
			case 3:
				mNodeIcon = "tvnCommunity.png";
				break;
			case 4:
				mNodeIcon = "tvnAuthority.png";
				break;
				
			case 6:
				mNodeIcon = "tvnAdmin.png";
				break;
				
				ADMINPERSON
		}
		
		
		
		var treeViewNode = document.createElement("div");
		treeViewNode.id = "treeViewNode("+aTvDataSet['id']+")";
		treeViewNode.className = "treeViewNode";
		treeViewNode.className = "treeViewNode_RootItem";
		
		
		
		// das ist das eigentliche Node, hier müssen alle Eigenschaften definiert sein
		//*** parent, icon, content, db-id, etc
		var treeViewNodeItem = document.createElement("div");
		treeViewNodeItem.className = "treeViewNodeItem";
		treeViewNodeItem.id = "treeViewNodeItem("+aTvDataSet['id']+")";
		treeViewNodeItem.onclick = function(){treeViewNode_onClick(this)};
		
		// setzen weiterer Attribute
		treeViewNodeItem.setAttribute("dbid", aTvDataSet['id'], 0);
		treeViewNodeItem.setAttribute("parent", treeViewParent.getAttribute("dbid"), 0);
		treeViewNodeItem.setAttribute("parentNodeId", treeViewParent.id, 0);
		treeViewNodeItem.setAttribute("type", aTvDataSet['type'], 0);
		treeViewNodeItem.setAttribute("tname", aTvDataSet['tname'], 0);		
		treeViewNodeItem.setAttribute("numberOfChilds", aTvDataSet['numberOfChilds'], 0);
		// hier wird gesetzt ob das NodeItem aufgeklappt werden kann
		if( (aTvDataSet['numberOfChilds']*1) > 0)					
			treeViewNodeItem.setAttribute("canExpand", true, 0);
		else
			treeViewNodeItem.setAttribute("canExpand", false, 0);
			
			
		
		// hier wird isExpanded auf false gesetzt
		treeViewNodeItem.setAttribute("isExpanded", "false", 0);
		
		// das hier ist das image, das muss je nach type anders geladen werden
		var treeViewNodeIcon = document.createElement("img");
		treeViewNodeIcon.className = "treeViewNodeIcon";
		treeViewNodeIcon.id = "treeViewNodeIcon("+aTvDataSet['id']+")";
		treeViewNodeIcon.src = "styles/images/"+mNodeIcon;
		treeViewNodeIcon.width = 25+"px";
		treeViewNodeIcon.height = 25+"px";		
		
		
		
		// hier steht nur der Text eines Node drin
		var treeViewNodeContent = document.createElement("span");
		treeViewNodeContent.className = "treeViewNodeContent";
		treeViewNodeContent.id = "treeViewNodeContent("+aTvDataSet['id']+")";
		treeViewNodeContent.innerHTML = aTvDataSet['name'];
		
		
		
		// ein endFloat container, damit alles wieder richtig floatet
		var endFloat = document.createElement("div");
		endFloat.className = "endFloat";
		
		
		
		// treeViewNode wird zusammengebaut		
		treeViewNode.appendChild(treeViewNodeItem);
		treeViewNodeItem.appendChild(treeViewNodeIcon);
		treeViewNodeItem.appendChild(treeViewNodeContent);
		treeViewNodeItem.appendChild(endFloat);

		treeViewParent.appendChild(treeViewNode);
	}

das ClickEvent:
Code:
function treeViewNode_onClick(aTreeNode)
	{		
		var mTreeNode = document.getElementById("treeNode");

		myString = "<hr>";		
		myString += "HTML id: "+aTreeNode.id+"<br>";
		myString += "DBident: "+aTreeNode.getAttribute("dbid")+"<br>";
		myString += "parent: "+aTreeNode.getAttribute("parent")+"<br>";
		myString += "parentNodeId: "+aTreeNode.getAttribute("parentNodeId")+"<br>";
		myString += "type: "+aTreeNode.getAttribute("type")+"<br>";
		myString += "type name: "+aTreeNode.getAttribute("tname")+"<br>";
		myString += "No of Childs: "+aTreeNode.getAttribute("numberOfChilds")+"<br>";
		myString += "canExpand: "+aTreeNode.getAttribute("canExpand")+"<br>";
		myString += "isExpanded: "+aTreeNode.getAttribute("isExpanded")+"<br>";
		
		document.getElementById("pageWorkArea").innerHTML += myString;
		
		if( aTreeNode.getAttribute( "canExpand" ) == "true")
			loadtreeView(aTreeNode);
	}

So sieht das HTML Konstrukt dann aus:
ScreenShot.jpg

Eigentlich sollte jedes Node aus mehreren Elementen bestehen. Ein Container als Rahmen, der nur Farbe und Schrift definiert und weitere Attribute enthält. Ein Container für das Click Event und in diesem dann Ein Image als Icon und ein Span für den Text. Bei einem Click sollte dann auf gleicher Ebene wie der ClickContainer das neue Node geladen werden. Irgendwie verschachtelt es aber und wenn ich den letzten Child in der Kette klicke werden alle ClickEvents der Parents erneut ausgeführt. Das sieht dann so aus:

ScreenShot.jpg

Irgendwie funktioniert das nicht. Muss ich ein mit *.appendChild(...) erzeugtes Element noch terminieren?

LG deAndro
 
Zuletzt bearbeitet von einem Moderator:
Ändere mal
Code:
treeViewNodeItem.onclick = function(){treeViewNode_onClick(this)}
in
Code:
treeViewNodeItem.onclick = function(evt){treeViewNode_onClick(this, evt || window.event)}
und dann in
Code:
function treeViewNode_onClick(treeNode, evt) {
  if (typeof evt.stopPropagation !== 'undefined') {
    evt.stopPropagation();
  }
  else {
    evt.cancelBubble = true;
  }
  ...
}
das sollte verhindern, dass das Ereignis weiter propagiert wird.
 
Hi, ...
das war nicht das Problem. Es war eher ein logisches.
Ich habe versehentlich die Nodes in den Node mit dem Klick eingehängt, folglich wird jeder Click auch ein Event der Parents auslösen. Lösung war:

statt
Code:
treeViewParent = aParentNode;
		if(treeViewParent==null)
		{
			treeViewParent = document.getElementById("treeViewObject");
			treeViewParent.setAttribute("dbid", 0, 0);
		}

musste es so lauten:
Code:
treeViewParent = aParentNode;
		if(treeViewParent==null)
		{
			treeViewParent = document.getElementById("treeViewObject");
			treeViewParent.setAttribute("dbid", 0, 0);
		}
		else
			treeViewParent = aParentNode.parentNode;

Aber manchmal sollte man sich seinen Code am nächsten Tag noch mal in Ruhe ansehen wenn man nicht weiter kommt.

Aber Frage:
Was genau macht:
Code:
function(evt){treeViewNode_onClick(this, evt || window.event)}
? und was ist damit...:?
Code:
function treeViewNode_onClick(treeNode, evt) {
  if (typeof evt.stopPropagation !== 'undefined') {
    evt.stopPropagation();
  }
  else {
    evt.cancelBubble = true;
  }
  ...
}

Sorry wenn ich dumm frage, aber JavaScript ist neu für mich, bisher hatte ich .NET / VB&VBA, ... da gibt es solche Konstrukte nicht..
 
irgendwie funktioniert das nicht.... bei ->
Code:
mNodeContent.onclick = function(){
			treeViewNode_onClick(this, evt || window.event);
		}

kommt folgender Fehler:
evt is not defined
treeViewNode_onClick(this, evt || window.event);
 
Zuletzt bearbeitet von einem Moderator:
Mein Vorschlag war ja auch
Code:
treeViewNodeItem.onclick = function(evt){treeViewNode_onClick(this, evt || window.event)}
nicht was du jetzt benutzt hast. Bei deinem Versuch
Code:
mNodeContent.onclick = function(){
            treeViewNode_onClick(this, evt || window.event);
        }
fehlt das Argument "evt" der anonymen Funktion, das will dir auch die Fehlermeldung sagen.
 
In
Code:
treeViewNode_onClick(this, evt || window.event);
wird die Funktion namens "treeViewNode_onClick" mit zwei Argumenten aufgerufen, das erste Argument ist "this", also das Objekt, dessen onclick-Handler aufgerufen wird, das zweite Argument wird aus "evt || window.event" berechnet. "||" ist der Javascript "oder"-Operator, der hier ausgenutzt wird, um Unterschieden im Eventhandling zwischen IE (vor IE 9) und anderen Browsern gerecht zu werden. In IE (vor IE 9) werden Eventhandler vom Browser ohne Argument aufgerufen, es gibt aber dort ein globales window.event-Objekt. In anderen Browsern wird seit uralten Netscape-Zeiten ein Eventhandler mit dem Eventobjekt als Argument aufgerufen. "evt || window.event" sorgt also dafür, das entweder das vom Browser übergebene Eventobjekt oder das window.event-Objekt weitergereicht wird.
 
ah... ok. einleuchtend und es funktioniert ...
Wenn ich nun auch noch unterscheiden möchte ob es ein Single-Klick oder Double-Klick ist, bzw ein rechtsklick oder Klick der mittleren Maustaste, bzw des Laufrades, geht das und wenn ja wie?

Aktuell habe ich wenn ich einen Double-Click ausführe erst mal das Event für den Single-Click durchlaufen.

oh und frohe Weihnachten.
 

Neue Beiträge

Zurück