J'ai souvent besoin d'itérer une collection d'éléments pour déterminer si un ou plusieurs éléments ont une propriété particulière à un moment donné. Afin de déterminer le comportement qui se produit si la propriété en question est présente, j'efface un indicateur à l'aide d'un booléen et j'effectue une itération dans la collection, en définissant l'indicateur puis en agissant plus tard sur la valeur de l'indicateur.
Voici un exemple: p>
function disableButtonIfAnyFailuresVisible() {
var failureRows = $(this).find(".validation-row-failure");
anyVisible = false;
failureRows.each(function() {
if ($(this).is(":visible")) {
anyVisible = true;
}
});
if (anyVisible) {
$("#continue-button").prop("disabled", true);
}
}
Dans cette méthode, je veux trouver tous les éléments .validation-row-failure sur la page, et je veux vérifier s'ils sont visible ou non. S'il y en a des visibles sur la page, je souhaite empêcher l'utilisateur de continuer en désactivant le bouton Continuer.
Pour ce faire, je commence par définir le booléen anyVisible sur false, puis je parcours chaque élément de ma collection, si l'un d'entre eux est visible anyVisible code> est défini sur true et le conditionnel if (anyVisible) se déclenchera.
Comme je l'ai mentionné précédemment, j'utilise cette approche semi-fréquemment, mais je ne peux pas m'empêcher de pense que c'est une mauvaise façon de procéder à ce scénario particulier. J'aimerais savoir s'il existe d'autres moyens de meilleure qualité pour y parvenir?
3 Réponses :
Array.some () peut être ce que vous recherchez: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
Quelque chose en ce sens les lignes doivent fonctionner:
let failureRows = $(this).find(".validation-row-failure").toArray();
let anyVisible = failureRows.some(row => row.is(":visible"));
$("#continue-button").prop("disabled", anyVisible);
Votre approche est bonne, voici une version refactorisée plus stricte. Si vous voulez sortir d'une boucle .each () , ajoutez simplement return false à la fin de votre instruction if .
<table>
<tr class='fail'>
<td>FAIL</td>
</tr>
<tr class='fail'>
<td>FAIL</td>
</tr>
<tr class='fail'>
<td>FAIL</td>
</tr>
<tr class='fail'>
<td>FAIL</td>
</tr>
<tr class='fail'>
<td>FAIL</td>
</tr>
<tr class='fail'>
<td>FAIL</td>
</tr>
<tr class='fail'>
<td>FAIL</td>
</tr>
<tr class='fail'>
<td>FAIL</td>
</tr>
<tr class='fail'>
<td>FAIL</td>
</tr>
<button id='cont'>Continue</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
$(".fail").each(function() {
if ($(this).is(":visible")) {
$("#cont").prop("disabled", true);
return false;
}
});
Comme Markus Dresch l'a mentionné, Array.some () est une solution très soignée, spécialement conçue pour vérifier si un élément, correspondant à un certain motif, existe dans le tableau.
Juste une amélioration de votre solution - vous pouvez interrompre la boucle du tableau une fois que vous avez trouvé un élément correspondant:
anyVisible = false;
for(const row of failureRows) { // change from `.each()` to `for of`
if ($(this).is(":visible")) {
anyVisible = true;
break; // break once match is found
}
}
Jetez un œil à lodash et à toutes ses fonctions d'assistance. Plus précisément ici «_.any (...)». Bien sûr, vous pouvez également écrire vous-même ces aides. Si vous le faites, il est plus performant d'avoir une boucle for standard dans laquelle vous pouvez revenir plus tôt