Jump to content

DOM menu tree how to?


jc624

Recommended Posts

Hi,I'm trying to make a menu in DOM. So, when I click on each li (like yahoo) I would get the sublist (myArray list).This is what I have so far:

function initializeOptions() {	ic();}function ic() {var listA = document.getElementsByTagName("LI");listA.addEventListener ? nA.addEventListener('click', makeList, false) : attachEvent('onclick', makeList);}	//Arrayvar myArray = new Array(2)	myArray[0] = new mySites('google', 'I love ', '.com');	myArray[1] = new mySites('w3c', 'My favorite is ', '.org');//Constructor functionfunction mySites(name, text1, text2) {	this.length = 4;	this.name = name;	this.text1 = text1;	this.text2 = text2;}function makeList(event) {	var eTarget;		event.target ? eTarget = event.target : eTarget = event.srcElement;					var eUL = document.createElement('UL');				for (x = 0; x < myArray.length; x++) {					var eLI = document.createElement('LI');			var eA = document.createElement('A');			eA.setAttribute('href', 'http://www.' + myArray[x].name + myArray[x].text2);						var eAText = document.createTextNode(myArray[x].text1 + myArray[x].name);			eA.appendChild(eAText);			eLI.appendChild(eA);						eUL.appendChild(eLI);						}		document.body.appendChild(eUL);	function getTarget(x){		x = x || window.event;		return x.target || x.srcElement;	}			event.preventDefault ? event.preventDefault() : event.cancelBubble = true;				}

And here is the body info:

<body onLoad='initializeOptions();'><ul>	<li id="myArray1"><a href="#">Yahoo</a></li></ul></body></html>

I think I have the id specified wrong. Can anyone tell me how to do correctly. I also guess (well I think) I need to append up where i have the ic function...not sure....I'm just learning DOM so very new at this. Thanks so much!

Link to comment
Share on other sites

var listA = document.getElementsByTagName("LI"); listA.addEventListener ? nA.addEventListener('click', makeList, false) : attachEvent('onclick', makeList);
Maybe I'm missing a trick. Is nA a typo for listA? If so, can a list, collection, or array have a method like addEventListener ? If not, where did nA come from?
Link to comment
Share on other sites

Maybe I'm missing a trick. Is nA a typo for listA? If so, can a list, collection, or array have a method like addEventListener ? If not, where did nA come from?
Whoops it is a typo I meant listA not nA....I need to sleep..sorry
Link to comment
Share on other sites

I'm not entirely sure what you're asking, so I'll just throw out a few ideas. A lot of the action here is in your makeList function. I've never tried it your way, so I'm not 100% sure, but I'm close to sure, that you can't append a node to a node that isn't yet appended to the DOM structure. In other words, it looks like you're appending nodes in the wrong order.document.body.appendChild(eUL) needs to happen FIRSTTHEN eUL.appendChild(eLI);THEN eLI.appendChild(eA);THEN eA.appendChild(eAText);You can assign an ID (or any attribute) like this:element.id = "myID";ORelement.setAttribute("id","myID");Of course you can always specify an id in your markup:<span id="mySpan">I hope something here is helpful.

Link to comment
Share on other sites

Yes thank you! Had that idea...the only thing I'm struggling is where to put the function/strings (in what order). Basically I'll re-explained what I'm trying to do:As you can see I'm trying to make a dynamic list (kinda like a jtree) just doing it in DOM....hence the myArray list. So again I wanted to click on the 2 list on the body which is Yahoo and Google and then get a sublist. Of course there are other simple ways to do it in js and css but I'm trying it just in DOM (like creating elements in the script and not doing it within the body):So, so far what I realized is I NEEDED a for loop for the eventlistener of listA (it wasn't pointing out anywhere)...Also I did a getElementsbyTagName which I did the LI, and so far so good......with that, technically it doesn't matter how many LIs I have it just targets any LI, it also works in the A(dragging your mouse to yahoo/the link that is) because of the Parent (LI)...(thats the DOM advantage). Hope thats understandable.Alright now that that works, I want to be able to have the li point to myArray so it can dynamically open the sublist...if I can do that then I'll worry about the ids to determined defferent arrays and etc.Ok this is what I have so far after re-doing the code...(I left the alerts so hopefully that might help you to understand more) : ....So I guess now that I am able to actually get it halfway done I just need help on adding the sublist(myArray)...THANKS!

 function initializeOptions() {	ic();}function ic() {var listA = document.getElementsByTagName("li");alert(listA[0] + ' - '+listA.length);for (var x = 0; x < listA.length; x++) {	listA[x].addEventListener ? listA[x].addEventListener('mouseover', makeList, false) : listA[x].attachEvent('onmouseover', makeList);}}	//Arrayvar myArray = new Array(2)	myArray[0] = new mySites('google', 'I love ', '.com');	myArray[1] = new mySites('w3c', 'My favorite is ', '.org');//Constructor functionfunction mySites(name, text1, text2) {	this.length = 4;	this.name = name;	this.text1 = text1;	this.text2 = text2;}function makeList(event) {	var eTarget;		event.target ? eTarget = event.target : eTarget = event.srcElement;		alert(eTarget.nodeName);	}

and the body:

<body onLoad='initializeOptions();'><ul>	<li id="eTarget"><a href="#">Yahoo</a></li>	<li id=""><a href="#">Google</a></li></ul>

Link to comment
Share on other sites

Well, your first instinct was right. You need to loop through your array variables and create elements as you need them and assign them values from your array objects and append them where they go.I will suggest (ugly as it is) using innerHTML to put text in your anchors rather then digging for text nodes, at least till you have a working mechanism.So anyway, I think you're very close.

Link to comment
Share on other sites

Well, your first instinct was right. You need to loop through your array variables and create elements as you need them and assign them values from your array objects and append them where they go.I will suggest (ugly as it is) using innerHTML to put text in your anchors rather then digging for text nodes, at least till you have a working mechanism.So anyway, I think you're very close.
Hey thanks so much!!! You have been very helpful in understanding...yeah inner html......well what I was going to do is now add the function to create/make the array work - the code I had first which is:
	var eUL = document.createElement('UL');				for (x = 0; x < myArray.length; x++) {					var eLI = document.createElement('LI');			var eA = document.createElement('A');			eA.setAttribute('href', 'http://www.' + myArray[x].name + myArray[x].text2);						var eAText = document.createTextNode(myArray[x].text1 + myArray[x].name);			eA.appendChild(eAText);			eLI.appendChild(eA);						eUL.appendChild(eLI);						}		document.body.appendChild(eUL);			event.preventDefault ? event.preventDefault() : event.cancelBubble = true;

I'm not sure if I need all this but I'll try and experiment....if I get it I will sure post it.THANK YOU!

Link to comment
Share on other sites

Ok got it to work here' s what I have. All I needed to do is instead of document.body.appendChild(eUL); it needed to be eTarget.appendChild(eUL);.Look sibling within a sibling!....now to make the infinity(LIs) to stop (I guess this is where I need to do IDs). If anyone know please let me know.

function initializeOptions() {	ic();}function ic() {var listA = document.getElementsByTagName("li");alert(listA[0] + ' - '+listA.length);for (var x = 0; x < listA.length; x++) {	listA[x].addEventListener ? listA[x].addEventListener('mouseover', makeList, false) : listA[x].attachEvent('onmouseover', makeList);}}	//Arrayvar myArray = new Array(2)	myArray[0] = new mySites('google', 'I love ', '.com');	myArray[1] = new mySites('w3c', 'My favorite is ', '.org');//Constructor functionfunction mySites(name, text1, text2) {	this.length = 4;	this.name = name;	this.text1 = text1;	this.text2 = text2;}//element.setAttribute("id","nav");function makeList(event) {	var eTarget;		event.target ? eTarget = event.target : eTarget = event.srcElement;		if (eTarget.nodeName == 'LI') {						var eUL = document.createElement('UL');				for (x = 0; x < myArray.length; x++) {					var eLI = document.createElement('LI');			var eA = document.createElement('A');			eA.setAttribute('href', 'http://www.' + myArray[x].name + myArray[x].text2);						var eAText = document.createTextNode(myArray[x].text1 + myArray[x].name);						eA.appendChild(eAText);			eLI.appendChild(eA);			eUL.appendChild(eLI);			}						eTarget.appendChild(eUL);	event.preventDefault ? event.preventDefault() : event.cancelBubble = true;	}			}

Yeay!

Link to comment
Share on other sites

Might have to show us some code. the spec says addEventListener allows adding more than a single handler for an event, so I guess that's what you're after?, and I see you know about the IE version. So I can't guess what's wrong.Probloems removing nodes:Your reference is local and got clobbered when the addNode function quit?You're going after a node by an index instead of an id or tag and so you're removing a silly textnode instead of a content node?You're better than all of that, I think, so just show us some relevant code.Are you developing in Firefox, BTW? I learned almost everything I know from my error console and DOM inspector.

Link to comment
Share on other sites

Thanks. I'll keep working on it today. One thing though is I just realized that I need the var eTarget; global if I am inputting more functions for it.I'll keep at it and been focusing this more on FF and Safari.Here's what I tried :var eTarget; is global nowI added another evenlistener like this:

listA[x].addEventListener ? listA[x].addEventListener('mouseout', makeList1, false) : listA[x].attachEvent('onmouseout', makeList1);
and another function like this:
function makeList1(event) { event.target ? eTarget = event.target : eTarget = event.srcElement; eTarget.removeChild(eUL); event.preventDefault ? event.preventDefault() : event.cancelBubble = true; }
This might be the issue(actually I think it is, as the DOM inspector says its not define...just don't know how to rectified it though....getElement instead of create? Experimenting....Thanks!
Link to comment
Share on other sites

Alright...Here's the code so far:

/* variables */ var eTarget; /* constructors */function mySites(name, text1, text2) { this.length = 4; this.name = name; this.text1 = text1; this.text2 = text2;}/* arrays */var myArray = new Array()myArray[0] = new mySites('google', 'I love ', '.com');myArray[1] = new mySites('w3c', 'My favorite is ', '.org');/* runtime *//* functions */function initializeOptions() { ic();}function ic() { var listLI = document.getElementsByTagName('LI'); for (var x = 0; x < listLI.length; x++) { listLI[x].addEventListener ? listLI[x].addEventListener('mouseover', makeList, false) : listLI[x].attachEvent('onmouseover', makeList); listLI[x].addEventListener ? listLI[x].addEventListener('mouseout', removeList, false) : listLI[x].attachEvent('onmouseout', removeList); }}function setEvents(event) { event.target ? eTarget = event.target : eTarget = event.srcElement;}function makeList(event) { setEvents(event); if (eTarget.nodeName == 'LI') { var eUL = document.createElement('UL'); for (var x = 0; x < myArray.length; x++) { var eLI = document.createElement('LI'); var eA = document.createElement('A'); eA.setAttribute('href', 'http://www.' + myArray[x].name + myArray[x].text2); var eAText = document.createTextNode(myArray[x].text1 + myArray[x].name); eA.appendChild(eAText); eLI.appendChild(eA); eUL.appendChild(eLI); } eTarget.appendChild(eUL); event.preventDefault ? event.preventDefault() : event.cancelBubble = true; eTarget.removeEventListener ? eTarget.removeEventListener('mouseover', makeList, false) : eTarget.detachEvent('onmouseover', makeList); }}function removeList (event) { setEvents(event); if (eTarget.nodeName == 'LI') { if (eTarget.getElementsByTagName('UL').length > 0) { eTarget.removeChild(eTarget.lastChild); } eTarget.addEventListener ? eTarget.addEventListener('mouseover', makeList, false) : eTarget.attachEvent('onmouseover', makeList); }}
I got it to work! Yes!! removeChild to lastChild was the answer and also had to go back to the makeList function (loop it). Also made the target into setEvents (makes things easier)So am I done? Not quite. As you can see its doing it correctly BUT it mouseouts on any UL(like the child list of the main li).....I want it to mouseout on yahoos only so I have again more work to do.....Thanks for your help and I hope its helping peeps at the same time!
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...