Issues with document.appendChild() in JS

Viewed 57

I'm developing a web page of the game Mastermind, using images instead of colors. I generate the password using Math.floor(Math.random() * 6) + 1; to generate numbers from 1 to 6, and using that function to convert a number to an image:

var sam = document.createElement("img");
sam.src = "./samwell_tarly.jpeg";
var arya = document.createElement("img");
arya.src = "./arya_stark.jpeg";
var dany = document.createElement("img");
dany.src = "./dany.jpeg";
var jon = document.createElement("img");
jon.src = "./jon.jpeg";
var ned = document.createElement("img");
ned.src = "./ned_stark.jpeg";
var tyrion = document.createElement("img");
tyrion.src = "./tyrion.jpeg";
var ocu1 =  document.getElementById("oc1");
var ocu2 =  document.getElementById("oc2");
var ocu3 =  document.getElementById("oc3");
var ocu4 =  document.getElementById("oc4");

function intToGot(x) {
    if(x==1){return arya;}
    if(x==2){return sam;}
    if(x==3){return ned;}
    if(x==4){return dany;}
    if(x==5){return jon;}
    if(x==6){return tyrion;}
}

and then:

const oc1=Math.floor(Math.random() * 6) + 1;
ocu1.appendChild(intToGot(oc1));
const oc2=Math.floor(Math.random() * 6) + 1;
ocu2.appendChild(intToGot(oc2));
const oc3=Math.floor(Math.random() * 6) + 1;
ocu3.appendChild(intToGot(oc3));
const oc4=Math.floor(Math.random() * 6) + 1; 
ocu4.appendChild(intToGot(oc4));

Those are my divs:

            <div class="maiores" id="oc1"></div>
            <div class="maiores" id="oc2"></div>
            <div class="maiores" id="oc3"></div>
            <div class="maiores" id="oc4"></div>

The problem i am facing is that: When the numbers generated are all different, all of the 4 random images appear correctly, with no problems at all. But, when there is repetition, for example, if the password should be [sam,sam,dany,jon], only the last one of the repeated images appear, and the others just don't appear. In that case, the first 'sam' wouldn't appear. I can't understand how am I using wrong the appendChild function, and I need help to solve that problem.

2 Answers

solution

Explanation

This is because if a node is already a part of a document, then you cannot use that node reference again in another part of a document. If you do then the previous nodes get removed and inserted into new location.

const parent = document.querySelector("#parent");
const parent2 = document.querySelector("#parent2");

function createListChildElement(text) {
  const element = document.createElement("li");
  element.textContent = text;
  return element;
}

const firstListChild = createListChildElement("First");
parent.appendChild(firstListChild);

const secondListChild = createListChildElement("Second");
parent.appendChild(secondListChild);

parent2.appendChild(firstListChild);
<h1>Second List</h1>
<ul id="parent"></ul>

<h1>Second List</h1>
<ul id="parent2"></ul>

Solution

You can create a new node/clone and append it to a new parent. You can do this using cloneNode method node

const parent = document.querySelector('#parent');
const parent2 = document.querySelector('#parent2');

function createListChildElement( text ) {
  const element = document.createElement('li');
  element.textContent = text;
  return element;
}

const firstListChild = createListChildElement("First");
parent.appendChild( firstListChild );

const secondListChild = createListChildElement("Second");
parent.appendChild( secondListChild );

const clonedChild = firstListChild.cloneNode(true);
parent2.appendChild( clonedChild );
<h1>First list</h1>
<ul id="parent"></ul>

<h1>Second list</h1>
<ul id="parent2"></ul>

You've only made one image node for each character. It can only go in one place.

Just generate your images on the fly, instead of ahead of time.

function makeGot(fileName) {
  const n = document.createElement("img");
  n.src = filename;
  return n;
}

function intToGot(x) {
    if(x==1){return makeGot("arya_stark.jpeg");}
    if(x==2){return makeGot("samwell_tarly.jpeg");}
    if(x==3){return makeGot("ned_stark.jpeg");}
    if(x==4){return makeGot("dany.jpeg");}
    if(x==5){return makeGot("jon.jpeg");}
    if(x==6){return makeGot("tyrion.jpeg");}
}
Related