Why my forEach loop does not create the DOM elements from the array.length?

时间:2018-06-04 17:16:40

标签: javascript arrays dom foreach

I have been dealing with an issue for a while now. My problem is that I iterate an array with a loop but in the end, it just creates a single element. But my goal is to create a grid with cards

Here is my code.

    var array_of_elements = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12];
    var shuffled_array = shuffle(array_of_elements);
    var deck_of_cards = document.createElement("div");
    var cards = "";

  function newGame() {
            deck_of_cards.setAttribute("id", "card_deck");
            document.body.appendChild(deck_of_cards);

            /*  Loop throught all the array elemets and apply the class box*/
            shuffled_array.forEach(createElementBoard);
            deck_of_cards.innerHTML = cards;
        }

        /* Boarder creation  */
        function createElementBoard(i_cards) {
            cards = "<div class='box box-" + i_cards + "'></div>";
            return cards;
        }
newGame();

The code does not produce any errors.

enter image description here

Thanks

3 个答案:

答案 0 :(得分:1)

Array.prototype.forEach iterates over an Array but does not return anything (you shouldn't even be getting that "single element" (edit: as SpoonMeiser commented below, that seems to be an artifact of your global variable use)).

If you want to set innerHTML, you need a function that creates a string. This could be done in two ways:

You can use Array.prototype.map to create an array of strings, and then use Array.prototype.join to convert them to a single one.

function newGame() {
    deck_of_cards.setAttribute("id", "card_deck");
    document.body.appendChild(deck_of_cards);

    /*  Loop throught all the array elemets and apply the class box*/
    const cards = shuffled_array.map(createElementBoard);
    deck_of_cards.innerHTML = cards.join("");
}

/* Boarder creation  */
function createElementBoard(i_cards) {
    const card = "<div class='box box-" + i_cards + "'></div>";
    return card;
}
newGame();

Or, you can use Array.prototype.reduce

答案 1 :(得分:1)

There are a number of problems here.

What you're doing, is assigning the HTML for one card to the global variable cards, and overwriting it each time through your loop, so at the end, it's the HTML for just the last card.

If you change the line:

cards = "<div class='box box-" + i_cards + "'></div>";

to:

cards += "<div class='box box-" + i_cards + "'></div>";

It'll make the code work, but that's not the best solution.

Functions can return a value, communicating instead via a global is bad practice. Consider if you needed to re-run this function, whose responsibility would it be to reset cards? What if you ran it from multiple places, how would you ensure that they didn't interfere with each other?

Instead, consider this:

shuffled_array.forEach(function(i) {
    deck_of_cards.innerHTML += createElementBoard(i)
});

And stop cards being global:

function createElementBoard(i_cards) {
    var card = "<div class='box box-" + i_cards + "'></div>";
    return card;
}

答案 2 :(得分:0)

This is not possibly either you save cards data in global variable or put forEach implementation locally.

function newGame() {
    deck_of_cards.setAttribute("id", "card_deck");
    document.body.appendChild(deck_of_cards);

    /*  Loop throught all the array elemets and apply the class box*/
    var cards = "";
    shuffled_array.forEach(function(i_cards) {
        cards += "<div class='box box-" + i_cards + "'></div>";

    });
    deck_of_cards.innerHTML = cards;
}
newGame();