Boucle while s’exécute trop de fois

179148
,

Bjr

J'ai un script qui consiste à parcourir une liste de produit et cliquer dessus si le produit contient le mot clé recherché (ici en regex). Il faudrait reload la page et refaire l'action tant qu'aucune correspondance n'a été trouvée.
J'utilise donc une boucle while. Le problème est que l'action (du a la rapidité d’exécution de la boucle for) s'exécute trop vite et j'ai donc des milliers de reload en quelques secondes. Ducoup la code s'exécute dans le vide puisque la page n'a même pas le temps de chargée. (J'ai déjà essayé de mettre tout ça dans un window.onload mais ça marche pas)

  const keywords = '.*Bxer.*'.toLowerCase()
  const color = 'white'.toLowerCase()
  var ElementCount = document.querySelector('#container').childElementCount
  var r = 1

  while(r = 1) {

  for(var i=0; i < ElementCount; i++) {

    var element_product = document.querySelectorAll('#container > article > div > h1 > a')[i].innerText.toLowerCase()
    var element_color = document.querySelectorAll('#container > article > div > p > a')[i].innerText.toLowerCase()
    var regex_product =  new RegExp(keywords)
    var regex_color = new RegExp(color)

    if (element_product.match(regex_product) && element_color.match(regex_color)) {
      document.location.href = document.querySelectorAll('#container > article > div > h1 > a')[i].href
      r = 0
      break;
    }
    if (i == (ElementCount - 1) && !element_product.match(regex_product)) {
      i = 0
      document.location.reload(true)
    }
  }
  }

merci bcp,
matt

4 Réponse

5574
,

Bonjour,

Tu as fais une erreur bête au niveau de ton while. En effet, un simple "=" ne permet pas d'effectuer une vérification ( condition ) mais une attribution de valeur.

A chaque boucle, tu force r à 1 et le résultat d'une assignation de valeur à une variable c'est "true" (dire que tout s'est bien passé).
Au lieu de while(r = 1) utilise simplement while(r == 1) et tout devrait rentrer dans l'ordre.

179148
,

J'avais même pas vu, effectivement c'est une erreur bête merci. La boucle fonctionne maintenant mais j'ai toujours le même problème : elle n'attend pas la fin du chargement de la page pour se répéter. Ce qui donne donc des milliers de requête de .reload par minute et ne permet pas à la page de charger complètement pour pouvoir parcourir la liste de produit.

44803
,

Tu devrais peut-être lancer ta fonction dans un :

window.addEventListener('DOMContentLoaded', e => {
    // Ta boucle ici
})
179148
,

Ca marche absolument pas (mais merci quand même) et je pense savoir pourquoi.

Lorsque la boucle s'éxécute pour la première fois. La page est déjà chargée et donc l'event n'est pas capté.
De plus, même si ça marchait, je pense se répètera du moment que l'event est capté. Elle n'attendra pas que la page soit chargée entre chaque répétition.

Mon idée serait de faire l'inversse : on bloque le code à la fin de la boucle jusqu'a qu'il capte que la page soit chargée, puis on relance la boucle. Sauf que je sais pas vraiment comment faire ça. Un timeout ne bloquerait pas le code et même je ne sais pas quoi mettre en paramètre pour attendre un DOM loaded.
Ou alors mettre un event listener DOMcontent à la fin de la boucle, avec un break dedans, et empecher que la boucle ne se finisse et se répète sans le break (genre une boucle infinie à la fin mais ce serait barbare et pas du tout opti, c'est juste une idée pour modéliser mon exemple).

merci
matt