Conditional to check if all div´s have certain class?

Let´s say I have a bunch of divs, initially with the class “mini”:

<div id="container">
        <div class="mini">

        </div>
        <div class="mini">

            </div>
            <div class="mini">

                </div>
                <div class="mini">

                    </div>
                    <div class="mini">

                        </div>
    </div>

My script does some functionality and depending on what the user does, it starts adding a class (let´s say, “super”) to each of one of those div.

My issue:
Now i need my script to do something when ALL of the div have the class “super” added.

I have tried this:

const minis = document.querySelectorAll('.mini');

const checkIfAll = minis.every(mini => mini.classList.contains('super'))

See if that every function returs true, if it does i just have to do:

If (checkIfAll){
   do this
}

But it says: Uncaught TypeError: cards.every is not a function

I’m on my phone so sorry if I’m not very accurate but “every” is an Array method, your querySelectorAll gives you a collection but not a true Array, try to first transform that collection into a true Array.

omg you right! Now its working however it gives me always false, no matter if the div´s are already with the correct class.

Here´s what I did:

var testing = Array.from(cards)
const checkIfAll = testing.every(card => card.classList.contains('flip'));
console.log(checkIfAll) // always returns false in the console, regardless if all the div are already with the class "flip"

Do you have a link to your code?

I have https://jsfiddle.net/5ea279tu/ But note that since the images are located in my pc you can´t see them :frowning: sorry

I think every just accepts 1 parameter, a class, so instead, write the function that checks if an element contains the class, and then pass that function to the every(). Makes sense?

edit Sorry no, the code works fine, it returns true if all cards have the class"flip" and false if they don’t, must be something else like Randell points out.

The reason it always returns false, is that the code executes only one time (when the page loads) before any card has been clicked, so there are no divs with class of “flip”.

2 Likes

I see. I´ve done this:

function refreshData()
{
  var testing = Array.from(cards)
  const checkIfAll = testing.every(card => card.classList.contains('flip'));

    setTimeout(refreshData, 1*1000);
}

It works now! However I put the thing I want the script to do when is true (just an Alert, to test), and the problem is since I putting it inside the refresh function, it constantly alerts with “You Win”.

So I put it outside, but then it never appears:

// Win celebration:
function refreshData()
{
  var testing = Array.from(cards)
  const checkIfAll = testing.every(card => card.classList.contains('flip'));

    setTimeout(refreshData, 1*1000);
}

if (checkIfAll){
  alert("You win!")
}

refreshData();

Where do you think can I put it then?

Why do you have refreshData calling itself every second (the setTimeout is doing this)?

Because the alert(“You win”!) message must pop up when the user completes the game, so I´m checking with that function every second if the user has completed the game (meaning, all the div are with the class “flip”)

You only need to check if the user has won the game after flipping a tile. There is no need to check every second.

1 Like

EDIT–Solved it again. I think it can be closed this thread

Ok, so I just solved it too but again I have another bug :sweat_smile: Now the alert pops up two times. I don´t understand why? Here´s the function:

function checkWin()
{
  var testing = Array.from(cards)
  const checkIfAll = testing.every(card => card.classList.contains('flip'));
  
  if (checkIfAll){
    alert("You win!")
  }
}

I put it here:

function doFlip() {

  if (lockBoard) return;
  if (this === firstCard) return;
	
  this.classList.add('flip');

  if (!hasFlippedCard) {
    
    hasFlippedCard = true;
    firstCard = this;
    return;
  }
  secondCard = this;

  setTimeout(checkWin, 2000)

  checkForMatch();
}

I did the setTimeout(checkWin, 2000) because checkWin() was displaying the alert pop up before the last card actually flipped. It was because I have some css transition so the card takes like 1 second to flip completely. So i thought using setTimeout to solve that (give checkWin a delay of 2 seconds so the card can have some time to flip) However now the alert pops up two times.

Is your jsFiddle up-to-date?

Nope. But I already solved everything. The thread can be closed. :slight_smile:

Glad you figured everything out. We don’t close these threads. We keep them open so others can read through and possibly benefit from reading the posts.