3
votes

Traverser l'axe suivant dans le DOM

Ceci est un fragment DOM.

<input class="click" type="button" value="1">
<p class="error"></ p>
<table>
<tr><td><input class="click" type="button" value="2"></td></tr>
</table>
<p class="error"></p>

Je voudrais trouver le p suivant avec la classe target , peu importe à quel niveau DOM le p pressé avec la classe click est. Dans le cas p avec la valeur 2

Quelque chose comme

$ ("p.click").click(function () {
target = $(this).following("p.target").first()
});

Mais je ne trouve pas comment parcourir l'axe suivant dans le DOM, sauf, peut-être, xpath qui ne fonctionne pas dans tous les navigateurs.

Ce serait génial si je ne sais pas quelque chose :)

Je n'ai pas été assez correct en écrivant la question. Un code plus approprié est ci-dessous. Après avoir appuyé sur cliquez , je souhaite obtenir la première erreur après

<p class="target">1</ p>
<p class="click"></ p>
<table>
<tr><td><p class="click"></p></td></tr>
</table>
<p class="target">2</p>


0 commentaires

3 Réponses :


0
votes
$ ("p.click").click(function () {
target = $(this).nextAll("p.target").first() // following-->nextAll
});
Here is your playground

0 commentaires

1
votes

En récupérant tous les p au départ, vous pouvez vérifier le .index de l'élément cliqué ( this ) dans la collection. Ensuite, accédez à index + 1 dans cette p collection:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="click" type="button" value="1">
<p class="error">1</p>
  <table>
    <tr>
      <td><input class="click" type="button" value="2"></td>
    </tr>
  </table>
  <p class="error">2</p>
const $ps = $('p');
const allElms = $('*');
$(".click").click(function() {
  const thisElmIndex = allElms.index(this);
  const followingElements = allElms.slice(thisElmIndex + 1);
  console.log(followingElements.filter('p')[0].textContent);
});

Si l'élément cliqué n'est pas nécessairement l'un des

de la collection dont vous vous souciez de l'index, vous pouvez suivre une méthode similaire en construisant une collection de tous éléments dans le HTML, trouver l'index de l'élément cliqué dans la collection, construire une nouvelle collection à partir de cet index + 1 , filtrer par p , et vérification du premier élément correspondant:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class="target">1</ p>
  <p class="click"></ p>
    <table>
      <tr>
        <td>
          <p class="click">click</p>
        </td>
      </tr>
    </table>
    <p class="target">2</p>
const $ps = $('p');
$("p.click").click(function() {
  const thisPIndex = $ps.index(this);
  console.log($($ps[thisPIndex + 1]).text());
});


9 commentaires

Belle approche! +1. Mais que se passe-t-il si click et target sont des éléments différents - par ex. bouton et p?


Si l'élément sur lequel vous avez cliqué n'est pas un

, comment déterminez-vous à quel

il est associé? Quel type de logique recherchez-vous? S'il s'agit d'un descendant, vous pouvez utiliser .querySelector , s'il s'agit d'un ancêtre, vous pouvez utiliser .closest


Réellement maintenant, c'est une grande forme dans laquelle les entrées sont placées dans des tables, des divs, etc. Mais après tout élément ou groupe d'éléments, p.error est placé pour afficher le résultat. Dans la plupart des cas, ils sont les suivants après l'entrée, mais parfois non


Sans voir le HTML et sans connaître le comportement souhaité, c'est difficile à dire


Voir edit, vous pouvez créer une collection pour tous les éléments du HTML, puis vérifier l'index de l'élément cliqué dans cette grande collection


Vous avez [0], valeur , en passant valeur comme deuxième paramètre. Voulez-vous dire [0] .textContent ? jsfiddle.net/mwLs87p1 (point au lieu de , )


Pour réduire la taille de la collection, dans le cas const $ ps = $ ('p.error'); const allElms = $ ('. click, p.error'); semble être mieux


Oui, si vous pouvez compter sur les éléments que vous voulez déclencher l'écouteur étant toujours des input s


J'ai déjà changé de sélecteur $ ('. Click, p.error'); - jsfiddle .net / ce0g4xhj



1
votes

.index () & .eq ()

En supposant qu'il y ait une .error pour chaque .clic , nous pouvons:

  • écoutez un clic sur n'importe quel .click
  • trouver le numéro d'index .click cliqué relatif à tous les .click du document
  • puis utilisez ce numéro d'index pour trouver le numéro d'index équivalent parmi les .error du document.


Démo

Détails commentés dans la démo

<input class="click" type="button" value="1">
<p class="error">ERROR 1</ p>
  <table>
    <tr>
      <td><input class="click" type="button" value="2"></td>
    </tr>
  </table>
  <p class="error">ERROR 2</p>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
.error {
  display: none
}
/*
- Register click event on document
  - Any .click clicked will be $(this)
- Get the index number of the clicked button in relation to
  all .click on the document.
- Use the same index number to find the associated .error
*/
$(document).on('click', '.click', function(e) {
  var idx = $(this).index('.click');
  $('.error').eq(idx).show();
});

3 commentaires

Bien que cela simplifie le code, mais dans une tâche réelle, il peut y avoir quelques clics pour une erreur. +1 de quelque manière que ce soit


Ouais, c'est en supposant que c'est un pour un. S'il y a plus d'un .click pour une seule .error alors un simple système de correspondance des valeurs d'attribut data- * fonctionnerait bien.


Je n'ai jamais pensé à DOM comme un tableau ordonné d'éléments. En raison des réponses, j'ai utilisé une telle approche et j'ai trouvé la solution rapide. Merci à tous, encore une fois