HervéRenault.fr

Logo non-officiel de JavaScript

Exemple de XPath en JavaScript

J'ai un vieux tableau dans lequel j'aimerais cocher les cases de toutes les lignes qui ont un lien qui commence par 2021 :

Illustration du vieux tableau

Voici le code JS simplifié qui utilise XPath en partant du principe que rien d'autre ne va modifier la page pendant son exécution :

var iterateur = document.evaluate("//td/a[starts-with(., '2021')]/../preceding-sibling::td/input", document);

var nœud = iterateur.iterateNext();

while (nœud) {
  nœud.checked = true;

  nœud = iterateur.iterateNext();
}

Mais si je veux aussi au passage mettre sur fond vert tous les liens qui commencent par 2021, je modifie le document et ça lance une exception :
DOMException: XPathResult.iterateNext: The document has been mutated since the result was returned

var iterateur = document.evaluate("//td/a[starts-with(., '2021')]", document);

var nœud = iterateur.iterateNext();

while (nœud) {
  nœud.style = 'background: limegreen';

  var ite2 = document.evaluate("../preceding-sibling::td/input", nœud);
  var n2 = ite2.iterateNext();

  n2.checked = true;

  nœud = iterateur.iterateNext();
}

Dans ce cas, il faut que je demande un cliché (snapshot) du DOM :

var cliché = document.evaluate("//td/a[starts-with(., '2021')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);

for (var i = 0; i < cliché.snapshotLength; i++) {
  var nœud = cliché.snapshotItem(i);

  nœud.style = 'background: limegreen';

  var itérateur = document.evaluate("../preceding-sibling::td/input", nœud);
  var n2 = itérateur.iterateNext();

  n2.checked = true;
}


MDN