简体   繁体   中英

element.appendChild() giving unexpected result: removes existing children

I am creating a 'photos' page on a website. It uses PHP to retrieve the filenames in a directory, and then attempts to create divs (with images in them) programmatically with javascript. However, when I try to create 'w3-third' divs, edit the innerHTML so that it embeds an image, and (the problematic step) add them to the 'w3-row' div, it removes the existing children. Hence, there is only one image per row.

I have been looking for alternate code / solutions, but the element.appendChild() function seems to be the only method; I have tried element.children.push(), but element.children is an [HTMLCollection] which (I guess) is read-only.

$.getJSON("content/photospage/get_filenames.php", function(data){
    var photoFileNames = data;
    console.log(photoFileNames.length + " images to display.");
    var photosDiv = document.getElementById("divPhotos");
    for(var i = 0; i < photoFileNames.length; i += 3){
      console.log("Loop! i=" + i);
      var newRow = document.createElement("div");
      newRow.classList.add("w3-row");
      newRow.classList.add("w3-padding-8")

      var newImg1 = newImg2 = newImg3 = document.createElement("div");

      newImg1.classList.add("w3-third")
      newImg2.classList.add("w3-third")
      newImg3.classList.add("w3-third")

      newImg1.innerHTML = "<img src='" + dir + photoFileNames[i] + "' class='w3-round w3-margin-bottom constrained'>";
      newRow.appendChild(newImg1);
      console.log("displayed img " + (i))
      if(i+1 < photoFileNames.length){
        newImg2.innerHTML = "<img src='" + dir + photoFileNames[i+1] + "' class='w3-round w3-margin-bottom constrained'>";
        newRow.appendChild(newImg2);
        console.log("displayed img " + (i+1))
      }
      if(i+2 < photoFileNames.length){
        newImg3.innerHTML = "<img src='" + dir + photoFileNames[i+2] + "' class='w3-round w3-margin-bottom constrained'>";
        newRow.appendChild(newImg3);
        console.log("displayed img " + (i+2))
      }

      console.log(newRow.children);

      photosDiv.appendChild(newRow);
    }

The html element that exists by default:

<div class="w3-container w3-content w3-center w3-padding-32 " id="divPhotos">
</div>

Sorry for the large amount of code above. Thanks for any assistance, and I'm happy to clarify anything that I failed to mention. :)

Also, I am aware that the code is clunky and inefficient, so let me know if you pick up on anything I could do better. Thanks again! :)

With

var newImg1 = newImg2 = newImg3 = document.createElement("div");

you've created one object (an HTMLDivElement ) in memory, which 3 variable names ( newImg1 , newImg2 , newImg3 ) refer to. You do not have 3 separate elements. When you call appendChild with one of the elements, you remove it from wherever it previously existed in the DOM.

Since you want separate elements, you should do so explicitly:

var newImg1 = document.createElement("div");
var newImg2 = document.createElement("div");
var newImg3 = document.createElement("div");

You could make the code less repetitive by using another for loop instead of creating separate standalone elements:

for (let j = 0; j < 3; j++) {
  const thisIndex = i + j;
  if (thisIndex >= photoFileNames.length) {
    break;
  }
  const img = document.createElement("div");
  img.innerHTML =  "<img src='" + dir + photoFileNames[thisIndex] + "' class='w3-round w3-margin-bottom constrained'>";
  newRow.appendChild(img);
}

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