Pregunta

jQuery actualmente tiene .next(filter) y .nextAll(filter) pero necesito algo que encaja en el medio de estos -. Efectivamente, un .nextWhile(filter) que hace varias veces al lado hasta que el filtro ya no es así, entonces se detiene (en lugar de seguir hasta el final)

Para demostrar esto, el siguiente es algo de HTML simplificada -. (En realidad, se genera dinámicamente, de forma aleatoria / datos, más columnas, nombres de las clases apropiadas, y así sucesivamente)

<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>

Y en contra de este código JavaScript se ejecuta:

<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>

¿Hay una manera fácil de poner en práctica esta construcción nextWhile?

Lo ideal sería que esto debe lograrse sin modificar el código HTML actual.

¿Fue útil?

Solución

En jQuery puede crear nextWhile() equivalente utilizando nextUntil() método y Selección :not . En pocas palabras, while (condition is true) { do something } es lo mismo que decir until (condition is false) { do something } .

Considere este ejemplo truco en el que es necesario seleccionar todos los elementos .child que siguen a la primera .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>

El código siguiente es aproximadamente equivalente a .nextWhile(".child") y selecciona los tres elementos .child:

$("#test .parent:first").nextUntil(":not(.child)");

Otros consejos

ACTUALIZACIÓN:. abandonó la idea de recursividad y decidió contar y rebanada (véase el último ejemplo)

intento inicial:
Este código está libre de errores - que sólo devuelve los dos últimos elementos, por lo que no funciona para más de 3 artículos

.
jQuery.fn.nextWhile = function(f)
{
    if( this.next(f).html() )
    {
        return this.next(f).nextWhile(f).andSelf();
    }
    else
    {
        return this;
    }
};


Versión actual:

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);
}

Esto parece funcionar bien, pero no estoy seguro de si hay algún penalizaciones de rendimiento a la selección de todo y luego rebanar sólo un puñado de ella?

Mi versión:

$.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;
  }
});
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top