Prototype - Get the IDs from .childElements()

OK, simple script that currently takes an array of ID values (hard coded) and then iterates through them to fade in and out creating a slideshow.

The obvious problem is I have to hard code the number of DIVs in the slideshow. What I really want is the code to get the child elements of the container I pass it and then iterate through them dynamically.

Here’s what I’ve got so far from http://mikeomatic.net:


var divs_to_fade = new Array("box-1", "box-2", "box-3", "box-4", "box-5");

var fade_i = 0;
			
var fade_wait = 5000;

function swapFade() {
	Effect.Fade(divs_to_fade[fade_i], { duration:1, from:1.0, to:0.0 });
	fade_i++;
	if (fade_i == 5) fade_i = 0;
	Effect.Appear(divs_to_fade[fade_i], { duration:1, from:0.0, to:1.0 });
}

I thought of trying something like this:


var divs_to_fade = $('crossfade-container').childElements();

var fade_i = 0;
			
var fade_wait = 5000;

function swapFade() {
	Effect.Fade(divs_to_fade[fade_i], { duration:1, from:1.0, to:0.0 });
	fade_i++;
	if (fade_i == divs_to_fade.length) fade_i = 0;
	Effect.Appear(divs_to_fade[fade_i], { duration:1, from:0.0, to:1.0 });
}

Problem with that is $(‘crossfade-container’) isn’t defined yet. I’m sure I should set that at the ONLOAD, but I was having issues then passing it to the swapFade() function, as swapFade() is called by a function that has

setInterval('swapFade()',fade_wait);

Can I set it globally in the ONLOAD and reference it in swapFade? Or do I need to keep passing it along to each of the functions?

The second part is how do I then iterate through the objects returned by .childElements() and pass the ID to swapFade()?

Any help is greatly appreciated.

something similar to this

 
divs_to_fade = new Array();
 
var childDivs = document.getElementById("slideshowContainerID").childNodes;
 
//loop thru divs and add each div's id to the array
for(var i=0; i < childDivs.length; i++) {
      divs_to_fade.push(childDivs[i].id);
}
 

OK, so I now have this


function assembleRotate(){
	divs_to_fade = new Array();
 
	var childDivs = document.getElementById("crossfade-container").childNodes;
 
	//loop thru divs and add each div's id to the array
	for(var i=0; i < childDivs.length; i++) {
      divs_to_fade.push(childDivs[i].id);
	}
	alert(divs_to_fade);
	startRotate(divs_to_fade);
}
		
var fade_i = 0;
			
var fade_wait = 5000;

function swapFade(divs_to_fade) {
	Effect.Fade(divs_to_fade[fade_i], { duration:1, from:1.0, to:0.0 });
	fade_i++;
	if (fade_i == 5) fade_i = 0;
	Effect.Appear(divs_to_fade[fade_i], { duration:1, from:0.0, to:1.0 });
}
			
function startRotate(divs_to_fade) {
	setInterval(function() { swapFade(divs_to_fade); },fade_wait);
}

This alerts

,box-1,,box-2,,box-3,,box-4,,box-5,

and throws an element is undefined error.

Did I do something stupid with the syntax? Seems a bit odd to have that many commas. The HTML is just DIVs with a single image inside.


[COLOR=#000066][COLOR=black][COLOR=#000066]alert[/COLOR][COLOR=#66cc66]([/COLOR]divs_to_fade[COLOR=#66cc66])[/COLOR];
[/COLOR]
[/COLOR]

you can’t use alert() like this to display the contents of an array. (divs_to_fade is an array containing element id’s and not a string).
[COLOR=#000066]
alert() displays a text message only.

if you want to see what element id’s have been entered into divs_to_fade you need to loop through the array elements and build a string containing the element values and display the string after the loop or display each element value individually.

to see the id’s in divs_to_fade


[COLOR=black]for(var i=0; i < divs_to_fade.length; i++) {[/COLOR]
[COLOR=black]   alert(divs_to_fade[i]);[/COLOR]
[COLOR=black]}[/COLOR]

[/COLOR]

I understand that, but it did uncover the fact that there were “undefined” values in the array, hence the added commas in the alert.

I am alerting the childDivs.length and it displays 11. This is definitely the issue, as there are only 5 direct child DIVs. There are 11 elements total if you add the container and all descendants (img tags within the divs).

Is there an issue with

var childDivs = document.getElementById("crossfade-container").childNodes;

Or is perhaps whitespace or carriage returns causing extra child nodes? Should I switch this to a

getElementsByTagName('div')

I thought that’s what childNodes would do!

ooops :headbang: this has come up before.

a document has different node types and .childNodes could be picking up some other extraneous nodes like attribute nodes. I’m not exactly sure how it works, but the “fix” is we need to check for node type before adding the element id to the array

try

 
//loop thru divs and add each div's id to the array
for(var i=0; i < childDivs.length; i++) {
    if(childDivs[i].nodeType == 1) {
          divs_to_fade.push(childDivs[i].id);
    }      
}

Thats the ticket! Works like a charm! Thanks!

Here’s the full code for anyone following along


function assembleRotate(){
	divs_to_fade = new Array();
 
	var childDivs = document.getElementById("crossfade-container").childNodes;
 	
	for(var i=0; i < childDivs.length; i++) {
    	if(childDivs[i].nodeType == 1) {
		divs_to_fade.push(childDivs[i].id);
		}      
	}

	startRotate(divs_to_fade);
}

var fade_i = 0;
			
var fade_wait = 5000;

function swapFade(divs_to_fade) {
	Effect.Fade(divs_to_fade[fade_i], { duration:1, from:1.0, to:0.0 });
	fade_i++;
	if (fade_i == divs_to_fade.length) fade_i = 0;
	Effect.Appear(divs_to_fade[fade_i], { duration:1, from:0.0, to:1.0 });
}
			
function startRotate(divs_to_fade) {
	setInterval(function() { swapFade(divs_to_fade); },fade_wait);
}

Then just call assembleRotate() on pageload

you’re welcome - glad it’s sorted out :slight_smile: