简体   繁体   中英

JavaScript ignores appendChild in 2nd and 4th loop

Here's the fiddle that successfully does what I am trying to do: http://jsfiddle.net/WoofurrBro/qcf4qcm6/2/

And here is my setup that's not working.

 function align() { var x = document.getElementById('container').offsetWidth; var y = document.getElementsByClassName('box')[0].offsetWidth; var z = Math.floor(x / y); // finds # of columns for (var i = 0; i < z; i++) { document.getElementById('container').innerHTML += '<div class=col style="width:' + y + 'px;float:left;"></div>'; }; // creates columns var columns = document.getElementsByClassName('col'); var boxes = document.getElementsByClassName('box'); // variables for later use /////////////////////////////////////////////////////////////////////////////// for (var i = 0; i < boxes.length; i++) { var minIndex; var column = []; // minIndex = shortest column, column[] to sort NodeList for (var iii = 0; iii < columns.length; iii++) { column[iii] = columns[iii].clientHeight; }; // converts columns[] (NodeList) to column[] (Array) column.sort(function (a, b) { return a - b; }); // sorts the column[] array for (var ii = 0; ii < columns.length; ii++) { if (column[0] == columns[ii].clientHeight) { minIndex = ii; break; }; }; // picks the first item in the column[] array (shortest) and finds the index of it in columns[] NodeList boxes[i].style.visibility = 'visible'; //ALSO, placing this under the appendChild string causes weird bugs (?) boxes[i].innerHTML += i + 'h'; columns[minIndex].appendChild(boxes[i]); // !!!!!!!!!!!!!! SEEMS TO IGNORE THIS appendChild //places them and adds identification }; /////////////////////////////////////////////////////////////////////////////// }; window.onload = align; 
  * { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; cursor:default; margin:0px; padding:0px; } html { background-color:#20293F; } #title { text-align:center; padding-top:40px; font-size:60px; margin-bottom:10px; } #description { font-size:14px; text-align:center; margin:0 auto 30px auto; max-width:450px; } .box { width:250px; word-wrap:break-word; background-color:rgba(0, 0, 0, 0.30); margin:10px 0 10px 0; } col { margin:0 10px 0 10px; } #containerwrap { background-color:rgba(0, 0, 0, 0.30); min-width:800px; width:100%; } #container { overflow:hidden; width:800px; margin:0 auto; } .postTitle { text-align:center; font-size:30px; color:#5F70A6; } .postBody { padding:10px; font-size:12px; color:#5F70A6; } 
 <div id="containerwrap"> <div id="container"> <div class="box"> <h2 class="postTitle">11 boots</h2> <div class="postBody"> <p>11 bbooots</p> </div> </div> <div class="box"> <h2 class="postTitle"></h2> <div class="postBody"> <p>22 sweg</p> </div> </div> <div class="box"> <h2 class="postTitle"></h2> <div class="postBody"> <p><span></span><span></span><span>33 thisisadivthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimetocopythisshitsorries<span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span><span>divthingwithoutanyspanssodontevenexpectthehtmltogeneratespanslikeitdidlasttimebitchtimeto</span></span> </p> </div> </div> <div class="box"> <h2 class="postTitle">44 ether</h2> <div class="postBody"> <p>44 infinite, silk-smooth darkness covers your eyes as you float in the skies <br>lightning bolts of pleasure and happiness strike you, through your senses, as each rain drop pops silently on your skin <br>the windy silence cloak guards your peace as you rest in the sky, floating upwards and feeling the rain drops pop and the air flowing around you with kind love, giving you calmness and calmness again <br>this sea of magic around you might not be, but does it matter, if that's what's on your mind. you let it stay and you float, you float away, as you let it be <br>and it strikes you that you are where your mind is and your mind is here, here in this magic place, as the raindrops pop lightning on your skin, you allow it to be, might you never leave, but if you ever left, might you come back to be here once more <br>just close your eyes</p> </div> </div> </div> </div> 

Before the code runs, the boxes start out in the order 11 22 33 44, and I want the script to dynamically create three columns and place them one at a time into whichever is the shortest column at each step.

However, only two of the boxes are placed into columns. The 22 and 44 boxes are completely ignored and I don't know why.

What can I do to get it to work correctly?

appendChild() isn't being ignored. It's being repeatedly used on the same element.

If you look in the bottom corner of the 11 box, you will see:

0h2h3h

Your i + "h" text is getting added to the same box 3 times, which means that boxes[i] refers to the same box during 3 iterations of the loop.

How can this be? The issue here is that boxes is not an array. It's an HTMLCollection , and the order of its contents reflects the order of elements in the DOM at the current moment:

An HTMLCollection in the HTML DOM is live; it is automatically updated when the underlying document is changed.

Source

So this is what's happening:

Your boxes start out in the order:

[original boxes] 11 22 33 44   [columns]

So on the first iteration, boxes[i] is the 11 box and it's added to the first column. Now the order is:

[original boxes] 22 33 44      [columns] 11

On the next iteration, boxes[i] (aka boxes[1] ) is the 33 box and it's added to the second column, and the order is:

[original boxes] 22 44 11      [columns] 11 33

On the next iteration boxes[i] (= boxes[2] ) is the 11 box again , and it's appended to the third column. The order is now:

[original boxes] 22 44         [columns] 33 11

On the last iteration, boxes[i] is the 11 box yet again, and it's appended to the first column:

[original boxes] 22 44         [columns] 11 33

And that's the end of the story.


The reason why your jsfiddle works and your tumblr page doesn't is that in your tumblr page, the destination container is after the boxes' starting location, but in the jsfiddle, the container is before the boxes, so the unmoved boxes keep their ordinal positions the whole time.

Here is what your jsfiddle does if the container is moved to be after the boxes:

http://jsfiddle.net/qcf4qcm6/3/


The fix for this is simple. Just convert boxes into an array before you start using it:

 var boxes = document.getElementsByClassName('box'); boxes = Array.prototype.slice.apply(boxes); 

Do that, and everything should work alright.

http://jsfiddle.net/myqakknr/2/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM