javascripthtmlarraysdom-manipulationhtmlcollection

Appending elements to children of HTMLcollection


I am trying to loop through an HTMLcollection and append a newly created element to respective children. There are 3 conditions I am looking out for if the children have 1 of 3 classes:

  1. type-freebie
  2. type-hack
  3. type-post

I have been able to set most of it up and successfully attach the element I need to each distinct group, however, when two or more of any distinct type appear, only one gets appended and the other one does not. I have tried to figure out what the problem and I think it has to do with something with HTMLcollections not working like arrays but I can't seem to be able to place my finger on it.

I have pasted the code snippets below of what I have so far and the HTML I am trying to manipulate in the DOM after it.

Would appreciate any insights I might be missing.

const card_Group = jQuery('#latest-cst-query > .elementor-widget-container > .elementor-posts');

const cf_div = document.createElement("a");
const ch_p = document.createElement("a");
const cp_a = document.createElement("a");

for (cards of card_Group) {
let cardChild = cards.children;
for (card of cardChild){
    if (card.classList.contains("type-freebie")){
       cf_div.classList.add("freebie_tax", "freebie_fcol");
       cf_div.innerText = "Freebie";
    card.firstElementChild.append(cf_div);
   } if (card.classList.contains("type-hack")){
       ch_p.classList.add("freebie_tax", "freebie_hcol");
       ch_p.innerText = "Hack";
       card.firstElementChild.append(ch_p);
   } if (card.classList.contains("type-post")) {
       cp_a.classList.add("freebie_tax");
       cp_a.innerText = "Blog";
       card.firstElementChild.append(cp_a);
   }
}
}

Solution

  • The issue here is that you create only one element per group and when appended second time it actually being moved instead.

    So what you need to do is create new element before it's appended.

    for (card of cardChild){
        if (card.classList.contains("type-freebie")){
           let cf_div = document.createElement("a");
           cf_div.classList.add("freebie_tax", "freebie_fcol");
           cf_div.innerText = "Freebie";
           card.firstElementChild.append(cf_div);
        }
    

    You can even clone it too:

    const cf_div = document.createElement("a");
    cf_div.classList.add("freebie_tax", "freebie_fcol");
    cf_div.innerText = "Freebie";
    
    for (card of cardChild){
        if (card.classList.contains("type-freebie")){
          card.firstElementChild.append(cf_div.cloneNode(true));
        }