PDA

View Full Version : javascript loop skipping intervals, why?



ahs10
10-01-2009, 04:45 PM
i know there are pre-made scripts to do what i'm doing, in fact i think dd offers one. i want to create this myself to learn.

i'm trying to create a list of section titles with arrows next to them, clicking on an arrow expands the section to read it's text, clicking on the arrow again collapses the section text. additionally, i would like an "expand all" and "collapse all" link and that's where my issue baffles me.

my js -


function expandAll() {
var collapsedDivs = document.getElementsByClassName('collapsed');
for (var i=0; i<collapsedDivs.length; i++) {
var expandMe = collapsedDivs[i];
expandMe.style.display = 'block';
expandMe.addClassName('expanded');
expandMe.removeClassName('collapsed');
document.getElementById('arrow_'+i).innerHTML = '<img src="../media/hide.gif" />';
}
}



my html -


<div style="float:left" id="arrow_0"><img src="../media/show.gif" /></div><div style="margin-left:20px; text-align:left; font-weight:bolder; font-size:14px">SECTION ONE TITLE</div>
<div class="collapsed" style="margin-left:20px; margin-right:30px; text-align:left; display:none">Section one text text text text text text text text text text text text text text text text text text text text text text </div>
<div style="float:left" id="arrow_1"><img src="../media/show.gif" /></div><div style="margin-left:20px; text-align:left; font-weight:bolder; font-size:14px">SECTION TWO TITLE</div>
<div class="collapsed" style="margin-left:20px; margin-right:30px; text-align:left; display:none">Section two text text text text text text text text text text text text text text text text text text text text text text </div>
<div style="float:left" id="arrow_2"><img src="../media/show.gif" /></div><div style="margin-left:20px; text-align:left; font-weight:bolder; font-size:14px">SECTION THREE TITLE</div>
<div class="collapsed" style="margin-left:20px; margin-right:30px; text-align:left; display:none">Section three text text text text text text text text text text text text text text text text text text text text text text </div>
<div style="float:left" id="arrow_3"><img src="../media/show.gif" /></div><div style="margin-left:20px; text-align:left; font-weight:bolder; font-size:14px">SECTION FOUR TITLE</div>
<div class="collapsed" style="margin-left:20px; margin-right:30px; text-align:left; display:none">Section four text text text text text text text text text text text text text text text text text text text text text text </div>


upon executing the function, the result is the text for sections one and three being expanded and the arrows for one and two being changed. why? what am i doing wrong?

jscheuer1
10-01-2009, 06:26 PM
collapsedDivs is not a true array, it is a nodelist. As you loop through it, you are also removing nodes from it, changing both its length property and the indexes (their 'i' in this case) of the remaining members.

I've often found that in situations like this, one can loop backward through the list:

for (var i = collapsedDivs.length - 1; i > -1; --i) {

I'm not sure if this will work here. If not, one must turn the nodelist into a true array before processing:


for (var collapsedDivs = [], i = document.getElementsByClassName('collapsed').length - 1; i > -1; --i){
collapsedDivs[i] = document.getElementsByClassName('collapsed')[i];
}
for ( i=0; i<collapsedDivs.length; i++) {
var expandMe = collapsedDivs[i];
expandMe.style.display = 'block';
expandMe.addCl . . .

Note: A similar issue arises when looping through an array while also removing elements from that array.

ahs10
10-01-2009, 08:12 PM
thank you very much! not only a great suggestion on how to repair it, but the correcting my definition of collapsedDivs as a node list instead of an array, is just priceless.

i'm going to go correct a few definitions out in the www of what getElementsByClassName really does. you rock! cheers!