jQuery - suggestions pour un « prochain Alors que » traversal?
-
23-08-2019 - |
Question
jQuery a actuellement .next(filter)
et .nextAll(filter)
mais je besoin de quelque chose qui correspond au milieu de ces -. Efficacement, un .nextWhile(filter)
qui fait à plusieurs reprises suivant jusqu'à ce que le filtre ne soit plus vrai, arrête (plutôt que de continuer à la fin)
Pour le démontrer, ce qui suit est une HTML simplifiée -. (En réalité, il est généré dynamiquement, un ordre aléatoire / données, plusieurs colonnes, les noms de classe appropriés, etc.)
<table>
<thead>
<tr>
<th>...</th>
</tr>
</thead>
<tbody>
<tr class="x"><td>a <button>Show/Hide</button></td></tr>
<tr class="x y"><td>a1</td></tr>
<tr class="x y"><td>a2</td></tr>
<tr class="z"><td>b</td></tr>
<tr class="z"><td>c</td></tr>
<tr class="x"><td>d <button>Show/Hide</button></td></tr>
<tr class="x y"><td>d1</td></tr>
<tr class="x y"><td>d2</td></tr>
<tr class="x y"><td>d3</td></tr>
<tr class="z"><td>e</td></tr>
<tr class="x"><td>f</td></tr>
<tr class="x"><td>g <button>Show/Hide</button></td></tr>
<tr class="x y"><td>g1</td></tr>
<tr class="x y"><td>g2</td></tr>
</tbody>
</table>
Et contre ce peu de JavaScript est exécuté:
<script type="text/javascript">
var $j = jQuery.noConflict();
$j().ready(init);
function init()
{
$j('tr.y').hide();
$j('tr.x button').click( toggleRelated );
}
function toggleRelated()
{
// Only toggles one row
// $j(this).parents('tr').next('.y').toggle();
// Toggles unrelated ones also
$j(this).parents('tr').nextAll('.y').toggle();
// Not currently a jQuery construct
// $j(this).parents('tr').nextWhile('.y').toggle();
}
</script>
Y at-il un moyen facile de mettre en œuvre cette construction nextWhile
?
Idéalement cela doit être réalisé sans modifier le code HTML en cours.
La solution
méthode et nextUntil()
a href = "http: / /api.jquery.com/not-selector/ » rel = "nofollow"> :not
sélecteur . Autrement dit, while (condition is true) { do something }
est la même que dire until (condition is false) { do something }
.
Considérez cet exemple de truc où vous devez sélectionner tous les éléments .child
qui suivent la première .parent
:
<ul id="test">
<li class="parent"></li>
<li class="child"></li>
<li class="child"></li>
<li class="child"></li>
<li class="divider"></li>
<li class="parent"></li>
<li class="child"></li>
<li class="child"></li>
<li class="child"></li>
</ul>
Le code suivant est à peu près équivalent à .nextWhile(".child")
et sélectionne les trois éléments de .child
:
$("#test .parent:first").nextUntil(":not(.child)");
Autres conseils
Mise à jour:. Gave sur l'idée de récursivité et a décidé de compter et tranche (voir l'exemple dernier)
initial Tentative: Ce code est bogué - il ne retourne que les deux derniers éléments, donc ne fonctionne pas pour 3 articles
.jQuery.fn.nextWhile = function(f)
{
if( this.next(f).html() )
{
return this.next(f).nextWhile(f).andSelf();
}
else
{
return this;
}
};
Version actuelle:
jQuery.fn.nextWhile = function(f)
{
var Next = this.next(f);
var Pos = 0;
while( Next.length > 0 )
{
Pos++;
Next = Next.next(f);
}
return this.nextAll(f).slice(0,Pos);
}
Cela semble fonctionner très bien, mais je ne sais pas s'il y a des pénalités de performance pour sélectionner tout, puis trancher seulement une poignée de celui-ci?
Ma version:
$.fn.extend({
nextWhile: function(selector) {
var $result = $([]);
this.each(function() {
var $next = $(this).next();
while ($next.is(selector)) {
$result = $result.add($next);
$next = $next.next();
}
});
return $result;
}
});