Prevent repeated Ivs from displaying

Asked

Viewed 41 times

0

I use the code below to display a div random class destino, however, when I perform the function, often the same div or the div previous repeat. There are ways to fix?

        function destino() {
            var E = document.getElementsByClassName("destino");
            var m = E.length;
            var n = parseInt(Math.random()*m);
            for (var i=m-1;i>=0;i--) {
                var e = E[i];
                e.style.display='none';
            }
            E[n].style.display='';
        }

1 answer

1


Your code is showing several divs random of the target class at a time because it has a for from a given number to 0.

As a solution to your problem you can store in an array those that have not yet been shown, calling it for example disponiveis, and fetch the div random to show from there:

//obter os divs existentes e guardar num array os que ainda não foram sorteados
let disponiveis = Array.from(document.getElementsByClassName("destino"));

function destino() {
    if (disponiveis.length == 0) return; //se não existem mais sai

    const n = parseInt(Math.random()*disponiveis.length); //sorteia apenas 1
    disponiveis[n].style.display=''; //mostra o sorteado

    disponiveis.splice(n,1); //remove do array o que foi sorteado
}

Notice I switched the elements to Array.from(document.getElementsByClassName("destino")) to get an array instead of an array HTMLCollection, which allows me to use later splice to remove an element.

Example:

let disponiveis = Array.from(document.getElementsByClassName("destino"));

function destino() {
  if (disponiveis.length == 0) return;

  const n = parseInt(Math.random() * disponiveis.length);
  disponiveis[n].style.display = 'block';
  disponiveis.splice(n, 1);
}

document.getElementById("sortear").onclick = function(){
  destino();
};
.destino {
  display:none;
}
<div class="destino">D1</div>
<div class="destino">D2</div>
<div class="destino">D3</div>
<div class="destino">D4</div>
<div class="destino">D5</div>
<div class="destino">D6</div>
<div class="destino">D7</div>

<button id="sortear">Sortear</button>

In the example if we wanted to keep the order in which it was drawn it would be better to add the drawn ones to another div:

let disponiveis = Array.from(document.getElementsByClassName("destino"));
const sorteados = document.getElementById("sorteados"); //div para sorteados

function destino() {
  if (disponiveis.length == 0) return;

  const n = parseInt(Math.random() * disponiveis.length);
  disponiveis[n].style.display = 'block';
  sorteados.appendChild(disponiveis[n]); //adicionar aos sorteados
  disponiveis.splice(n, 1);
}

document.getElementById("sortear").onclick = function(){
  destino();
};
.destino {
  display:none;
}
<div class="destino">D1</div>
<div class="destino">D2</div>
<div class="destino">D3</div>
<div class="destino">D4</div>
<div class="destino">D5</div>
<div class="destino">D6</div>
<div class="destino">D7</div>

<button id="sortear">Sortear</button>
<div id="sorteados"></div><!-- div para colocar os sorteados-->

Browser other questions tagged

You are not signed in. Login or sign up in order to post.