Acquire a set of picture cards for displaying in a grid layout

After creating a cardArray to store card objects, I went through each item in the array to generate images as cards. These card images were then appended to the grid div as children. Additionally, I set up an event listener for the shuffle button. However, I encountered challenges when trying to load the cards into the grid.

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">    
<title>Shuffle Picture Cards</title>
<script>

//create cards
const cardArray =[
{name:'bass',
img:'images/bass.png'},
{name:'bass',
img:'images/bass.png'},
{name:'burger',
img:'images/burger.png'},
{name:'burger',
img:'images/burger.png'},
{name:'jamaica',
img:'images/jamaica.png'},
{name:'jamaica',
img:'images/jamaica.png'},
{name:'mbappe',
img:'images/mbappe.png'},
{name:'mbappe',
img:'images/mbappe.png'},
{name:'napali',
img:'images/napali.png'},
{name:"napali",
img:'images/napali.png'},
{name:'racecar',
img:'images/racecar.png'},
{name:'racecar',
img:'images/racecar.png'},
]

//shuffle card array
cardArray.sort(() => 0.5 - Math.random())

//shuffle from shfl-btn
const shuffle = document.getElementById('shfl-btn');

//eventListener for click on shuffle button
shuffle.addEventListener('click', createBoard);

//get grid
const grid = document.querySelector('.grid');

//create cards board
function createBoard() {
for(let i=0; i < cardArray.length; i++) {
    var card = document.createElement('img')
    card.setAttribute('src', 'images/astart.png')
    //card.setAttribute('data-id', i)
    //card.addEventListener('click', flipCard)
    grid.appendChild(card)
    
}
}

</script>
<style>
body{
    box-sizing: border-box;
    align-items: center;
}
img{
    height:100px;
    width:100px
}

button{
    padding:10px;
    width:80px;
    border:solid black 2px;
    border-radius:4px;
    cursor:pointer;        
    margin-top:20px;
}
    
        
.grid{
    height:300px;
    width:400px;
    border:solid blue 4px;
    display: flex;
    flex-wrap: wrap;
    flex-direction: row;
    margin:0 auto;
    border-radius: 10px;
}

.shfl-btn{
    align-items: center;
    margin:0 auto;
    width:400px;    
}
.shuffle{
    margin-left:160px;
    
}
</style>
</head>
<body>
<h1>Shuffle picture cards</h1>
<div class="grid" id="grid">     
</div>

<div class="shfl-btn"><button class="shuffle"&g...

Upon calling the createBoard function, my aim is for the cards to populate and rearrange when the shuffle button is clicked.

Answer №1

Initially, there seems to be an issue with the event listener for your shuffle button. The code snippet shows:

//shuffle from shfl-btn
const shuffle = document.getElementById('shfl-btn');

However, it appears that you are trying to access the button element using the ID shfl-btn, whereas in the HTML code it is defined as a class on this line:

<div class="shfl-btn"><button class="shuffle">shuffle</button></div>

Since shfl-btn is actually a class, adding id="shfl-btn" would resolve this issue.


//create cards board
function createBoard() {
for(let i=0; i < cardArray.length; i++) {
    var card = document.createElement('img')
    card.setAttribute('src', 'images/astart.png')
    //card.setAttribute('data-id', i)
    //card.addEventListener('click', flipCard)
    grid.appendChild(card)
}
createBoard(); // <--- Here
}

It seems like there is a problem within the createBoard() function where it is being called repeatedly, creating an endless loop. Placing the call to this function outside should prevent it from endlessly looping.


In addition, including these two lines at the beginning of the createBoard() function can address some issues:

grid.innerHTML = ""; // Remove all the images from the grid before appending new ones.
cardArray.sort(() => 0.5 - Math.random()); // Shuffle it each time createBoard function is called.

Edit

The images seem to be not loading due to this line in the for loop:

card.setAttribute('src', 'images/astart.png');

Instead of setting all cards to the same image source, we should update it based on the values in cardArray. To do so, replace it with:

card.setAttribute('src', cardArray[i]['img']);

This will assign the correct image link to each card based on the value of 'img' in the cardArray.

Answer №2

Here's an alternate method for shuffling your cards.

//initialize cardArray with name and img properties
const cardArray = [{name:'bass',img:'https://picsum.photos/200'},{name:'bass',img:'https://picsum.photos/201'},{name:'burger',img:'https://picsum.photos/202'},{name:'burger',img:'https://picsum.photos/203'},{name:'jamaica',img:'https://picsum.photos/204'},{name:'jamaica',img:'https://picsum.photos/205'},{name:'mbappe',img:'https://picsum.photos/206'},{name:'mbappe',img:'https://picsum.photos/207'},{name:'napali',img:'https://picsum.photos/208'},{name:"napali",img:'https://picsum.photos/209'},{name:'racecar',img:'https://picsum.photos/210'},{name:'racecar',img:'https://picsum.photos/211'}];
//add click event listener to shuffle button
document.getElementById('shfl-btn').addEventListener('click', createBoard);
const grid = document.querySelector('.grid');

// Durstenfeld shuffle algorithm implementation
function shfl(a){
 for(let j,i=a.length;i>1;){
  j=Math.floor(Math.random()*i--);
  if (i!=j) [a[i],a[j]]=[a[j],a[i]]
 }
 return a
}
//create cards board with shuffled images
function createBoard() {
  grid.innerHTML=shfl(cardArray).map(c=>`<img src="${c.img}" title="${c.name}">`).join("");
}
createBoard();
body { box-sizing: border-box; align-items: center;}
img { height: 100px; width: 100px }
button { padding: 10px; width: 80px; border: solid black 2px; border-radius: 4px; cursor: pointer; margin-top: 20px;}
.grid { height: 300px; width: 400px; border: solid blue 4px; display: flex; flex-wrap: wrap; flex-direction: row; margin: 0 auto; border-radius: 10px;}
.shfl-btn { align-items: center; margin: 0 auto; width: 400px;}
.shuffle {margin-left: 160px;}
<h1>Shuffle picture cards</h1>
<div class="grid" id="grid"></div>
<div class="shfl-btn"><button class="shuffle" id="shfl-btn">shuffle</button></div>

In this code snippet, all HTML for the grid is generated at once and applied to the grid DOM element using a single .innerHTML assignment for efficiency.

A different shuffling algorithm, specifically Durstenfeld (a variation of the Fisher-Yates shuffle), is implemented in this snippet.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Dispatch prop within useEffect

App.js -> <Lobbies inGame={inGame} setLobby={setLobby} userName={userName} userKey={userKey}/> Lobbies.js -> import React, { useState, useEffect } from 'react'; import firebase from 'firebase'; const Lobby = ({userKey, ...

Setting a unique identifier for a newly created element in JavaScript and the DOM

Is there a way to assign an element ID to a newly created element using JavaScript DOM? The code I've written generates a table that is displayed when a button is clicked. I'm looking to give this table a unique ID so it can have a distinct sty ...

Ways to retrieve the initial key object received through an AJAX request

I have a form with three dynamic dropdowns. The second dropdown depends on the first one, and the third dropdown depends on the second one. Therefore, selecting an option in the first dropdown will automatically populate the next two dropdowns. Below is t ...

Assistance Required for Making a Delicious Cookie

Within my interface, there are two buttons displayed - one is labeled yes while the other is called no. <input type="button" name="yes" onclick="button()"> <input type="button" name="no"> In order to enhance user experience, I am looking to i ...

Efficiently adding values to a variable with the forEach method

I'm encountering an issue with displaying data from a JSON file similar to the one below: Currently, "checked" is set to null. I aim to update it to true within the steps array using a forEach loop. JSON data snippet: { "id": 4, "process": { ...

Run a JavaScript code to show a hidden element

My latest project involves automating tasks on a website using Selenium. I encountered an issue where I cannot click on a hidden button defined this way: <body> <div class="smenu" id="smenu4"> <input tabIndex="-1" type="button" ...

What potential issues arise from utilizing useRef alongside useSelector?

Although I have the capability to access the store by using thunks and/or global stores, I avoid binding my component to the Redux store. This is because the component will be utilized with various stores both inside and outside of the project. The compone ...

Tips for establishing communication between a React Native webView and a React web application

I am currently working on establishing communication between a webView in react-native and a web-app created with React-360 (and React). I am utilizing the react-native-webview library and following a guide for creating this communication. You can find the ...

How come the cubic bezier timing function works flawlessly just on the first try when staggered transitioning element opacity over time with CSS and a touch of JS?

I'm currently working on a menu overlay that expands to fill the screen when a user clicks a button in the corner. I'd like the menu items to fade in one by one, similar to the effect used on this website: Most of the functionality is there, but ...

Add a fresh text field with the click of a button and delete it with another button in Laravel 4

My form includes two fields: phone and email, as shown in the image below. By clicking on the plus button, I would like to add an additional text field to the form below the button. Similarly, by clicking on the minus button, I want to remove the text fie ...

What is the reason behind the failure of next/script with Google reCAPTCHA?

Currently, I am in the process of upgrading from next js version 8 to version 11. I wanted to take advantage of the amazing next js feature for "next/script". However, when I tried to implement it for Google reCAPTCHA using "react-recaptcha": "^2.3.10", th ...

Is it possible for the Redux inside a React component from npm to clash with the Redux in the container?

I am looking to bundle a React component with npm and incorporate Redux to handle state within the component. If another React project imports my component, will it cause conflicts with the Redux instance of that project? For example: The component code ...

Function not currently in operation

There seems to be an issue with the script not running or returning any answers. The console is blank. I am attempting to retrieve an answer from the Yandex Translate site (https://tech.yandex.com/translate/doc/dg/reference/translate-docpage/) Code: http: ...

Encountering the following error: Exceeded maximum call stack size limit

Currently, I am attempting to tackle a specific problem on LeetCode. This particular challenge involves calculating the power of x. However, upon executing my solution, an error message is displayed: RangeError: Maximum call stack size exceeded Here&apos ...

Did my code effectively block an XSS attack?

Recently, I was informed that my website has vulnerabilities to XSS attacks. In an effort to improve security, I have implemented the htmlspecialchars method as a preventive measure. Here is the function I created: function _e($string){ return htmlsp ...

Utilizing jQuery to extract the id and update its content

One of my tasks involves working with a table generated by PHP and incorporating a modal that allows users to change the text produced by the variable $l_id. I have a link with a class "eloc" that triggers the display of the modal div section. By intercept ...

Show and hide menu items without automatically scrolling the user back to the top of the page

I am currently working on a project where I have an image button that toggles between expanding and collapsing a menu using JavaScript. The issue I am facing is that every time the button is clicked, it takes the user back to the top of the page. My goal ...

Tips for incorporating data attributes into <figure> elements and retrieving them using CSS

Can we enhance a <figure> element by adding data attributes and then utilizing them in CSS? For example, I attempted figure { margin: 0 attr(data-margin %); } using <figure data-margin="15">...</figure> but it didn't yield the d ...

Issue with accessing Contacts API functionality in Firefox OS application

I have followed all the instructions provided in this documentation, but I keep encountering errors. My testing environment is the "Firefox OS 2.2" simulator. In my manifest file, I have included two permissions as follows: "permissions": { "deskto ...

Using a MySQL statement within a conditional statement

Looking to modify this code to display different information based on the values retrieved, here is the current code: $sql_doublecheck = mysql_query("SELECT * FROM adminpage WHERE setting='main' AND close_site='1'"); $doublecheck = mys ...