Domanda

jQuery ha attualmente .next(filter) e .nextAll(filter), ma ho bisogno di qualcosa che si inserisce nel mezzo di questi -. In modo efficace, un .nextWhile(filter) che fa ripetutamente successivo fino a quando il filtro non è più vero, poi si ferma (piuttosto che continuare fino alla fine)

A dimostrazione di ciò, il seguente è un po 'semplificata HTML -. (In realtà, viene generata dinamicamente, ordine casuale / dati, più colonne, i nomi delle classi adeguati, e così via)

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

E contro questo alcuni è gestito JavaScript:

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

C'è un modo semplice per implementare questo nextWhile costrutto?

Idealmente questo deve essere raggiunto senza modificare il codice HTML corrente.

È stato utile?

Soluzione

In jQuery è possibile creare nextWhile() equivalente utilizzando nextUntil() metodo e selettore :not . In poche parole, while (condition is true) { do something } è come dire until (condition is false) { do something } .

Considerate questo esempio trucco in cui si sono tenuti a selezionare tutti gli elementi .child che seguono la prima .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>

Il codice seguente è approssimativamente equivalente a .nextWhile(".child") e seleziona i tre elementi .child:

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

Altri suggerimenti

UPDATE:. rinunciato all'idea ricorsione e ha deciso di contare e fetta (vedi ultimo esempio)

tentativo iniziale:
Questo codice è buggy - restituisce solo gli ultimi due elementi, quindi non funziona per 3+ oggetti

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

Current Version:

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

Questo sembra funzionare bene, ma non sono sicuro se ci sono eventuali sanzioni prestazioni per selezionare tutto e poi affettare solo una manciata da esso?

La mia versione:

$.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;
  }
});
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top