0

I'm trying to make a memory game. I need to insert the cards into the HTML file with JavaScript. I've succeeded to do this with one card:

fruits = [`mangosteen image link`, `rambutan img link`, `pineapple img link`];

let insertCard = document.getElementById('containerId');
let cardBase = `/*bunch of other elements that have to repeat*/
<div class="card-front card-face">
    <img class="card-value card-img"
        src="${fruits[2]}">
</div>`;

insertCard.insertAdjacentHTML('beforeend', cardBase);

EDITED: How do I insert different values from the array into src="${array piece here}"> without just copying the code (a string(that is a link) once for the card)? And then the cards also have to be double (memory card matching game) And then move on to the next value (the img link) in the array?

Sorry if this is a stupid question, I'm very new to this all. Not using the correct terms and bad at explaining my problem too I guess. Is using template literals the wrong choice? I'm I doing the other way around? I've been trying to fix this for days now.

sabinemm
  • 1
  • 1
  • What I can't figure out is: *how to insert different values from the array into the src="${different fruits have to end up here}" and then *how to repeat that twice for each fruit(cause there have to be two cards to match) – sabinemm Mar 27 '20 at 15:21

2 Answers2

1

Create IMGs with fruits src:

const fruits = ['mangosteen image link', 'rambutan img link', 'pineapple img link'];

let cardBase = document.getElementsByClassName('card-front card-face')[0];
for (var f in fruits) {
  f = fruits[f];
  var i = document.createElement('IMG');
  i.src = f;
  cardBase.appendChild(i);
}
<div class="card-front card-face">
</div>

Remove all IMGs (childrens of parent container).

let cardBase = document.getElementsByClassName('card-front card-face')[0];
var i = cardBase.children;
for (var n = i.length; n;)
  cardBase.removeChild(i[--n]);

console.log(cardBase.outerHTML)
<div class="card-front card-face">
  <img src="mangosteen image link">
  <img src="rambutan img link">
  <img src="pineapple img link">
</div>
Jan
  • 2,178
  • 3
  • 14
  • 26
  • I cut out a bunch of stuff out of the cardBase just to make it shorter here and it's my bad for not specifying it therefore I don't think that it would work exactly? I guess? Also I did not understand the 'clean' part.. what i need to do is add cards with different links to the html.. I'm way over my head with this, so thank you for your time – sabinemm Mar 27 '20 at 14:25
  • Looks simple, but it is not to create/change HTML from strings without using DOM. – Jan Mar 27 '20 at 14:46
  • I am simply using standard document.createElement for creation and parent.appendChild or removeChild for adding / removing here. In case you do not understand these, you should study JS & DOM a bit... – Jan Mar 27 '20 at 14:48
  • Better now ? First snippet adds 3 images from your array. Second has hardcoded result of first, but removes them and shows parent code after remove to check what was done, when there is nothing visible. – Jan Mar 27 '20 at 14:56
0

The easiest procedural way, based on your current code, is to use Array.prototype.map() to loop over the Array of image-links:

const fruits = [`https://i.stack.imgur.com/4CAZu.jpg`,
                `https://i.stack.imgur.com/SqYhm.gif`, 
                `https://i.stack.imgur.com/a9xXV.png`];

let insertCard = document.getElementById('containerId');

// here we use Array.prototype.map() to iterate over the Array of image-links,
// and use an anonymous Arrow function to build an Array of template-literal
// HTML strings:
let cardBases = fruits.map(
  // the first argument, here 'href', a reference to the current Array-element,
  // the second argument, here 'index', a reference to the index of the current
  // Array-element:
  (href, index) => `<div class="card-front card-face">
   <span class="number">${index}</span>
    <img class="card-value card-img" src="${href}">
</div>`
);
// here we use Element.insertAdjacentHTML() to insert the created Array,
// after joining the Array elements together into one String via the
// Array.prototype.join() method:
insertCard.insertAdjacentHTML('beforeend', cardBases.join(''));
<div id="containerId"></div>

JS Fiddle demo.

Array.prototype.forEach() can also be used:

const fruits = [`https://i.stack.imgur.com/4CAZu.jpg`,
                `https://i.stack.imgur.com/SqYhm.gif`,
                `https://i.stack.imgur.com/a9xXV.png`];

let insertCard = document.getElementById('containerId');

// here we use Array.prototype.forEach() to iterate over the Array:
fruits.forEach(
  // As above, the first argument is a reference to the current Array-element,
  // the second is the index of that Array-element; here we use
  // Element.insertAdjacentHTML to insert the created HTML string on each
  // iteration of the loop; which works but triggers multiple repaints:
  // (this is somewhat dependant on browser implementations and may be
  // optimised away by individual browser engines):
  (href, index) => insertCard.insertAdjacentHTML('beforeend', `<div class="card-front card-face">
   <span class="number">${index}</span>
    <img class="card-value card-img"
        src="${href}">
</div>`)
);
<div id="containerId"></div>

JS Fiddle demo.

The above methods, of course, insert only one card for each image-link; to insert two 'cards' per link there's a couple of simple methods, String.prototype.repeat():

const fruits = [`https://i.stack.imgur.com/4CAZu.jpg`,
                `https://i.stack.imgur.com/SqYhm.gif`, 
                `https://i.stack.imgur.com/a9xXV.png`];

let insertCard = document.getElementById('containerId');
let cardBases = fruits.map(
  (href, index) => `<div class="card-front card-face">
   <span class="number">${index}</span>
    <img class="card-value card-img"
        src="${href}">
</div>`
);

// here we use Array.prototype.join() to create a String of the HTML
// contained within the cardBases Array; and then pass that String to
// the String.prototype.repeat() method, which takes the desired
// number of repetitions as an argument:
insertCard.insertAdjacentHTML('beforeend', cardBases.join('').repeat(2));
<div id="containerId"></div>

JS Fiddle demo.

The obvious caveat using String.prototype.repeat() is that it simply duplicates the supplied String, and doesn't allow for any simple means of shuffling that Array to randomise the cards' positions.

Another &endash; relatively simple &endash; means of duplicating the cards is to use Array.prototype.flatMap() and shuffling that resulting Array with the anonmyous function available to Array.prototype.sort():

const fruits = [
  `https://i.stack.imgur.com/4CAZu.jpg`,
  `https://i.stack.imgur.com/SqYhm.gif`,
  `https://i.stack.imgur.com/a9xXV.png`
];

let insertCard = document.getElementById('containerId');
let cardBases = fruits.map(
  // note that I finally remembered to remove the <span> containing
  // the index at this point:
  (href, index) => `<div class="card-front card-face">
    <img class="card-value card-img"
        src="${href}">
</div>`
// Array.prototype.map() returns an Array, here we pass that created
// Array to the Array.prototype.flatMap() method:
).flatMap(
  // the first argument is a reference to the current String of HTML;
  // here we return an two-element Array in which the current Array-
  // element is duplicated:
 (html) => [html,html]
// Array.prototype.flatMap() returns a one-dimensional 'flat' Array;
// here we pass that Array to the Array.prototype.sort() method:
).sort(
  // here we're generating a random number, and then checking to see
  // if that number is greater than 0.5; if it is we return 1, otherwise
  // we return -1; see the bibliography for a link to a question seeking
  // explanation of how Array.prototype.sort() works:
 () => Math.random() > 0.5 ? 1 : -1
);

insertCard.insertAdjacentHTML('beforeend', cardBases.join(''));
<div id="containerId"></div>

JS Fiddle demo.

References:

Bibliography:

David Thomas
  • 249,100
  • 51
  • 377
  • 410