2011-02-08 15 views
5

Qual è il modo migliore per rilevare le esecuzioni di elementi dom in jQuery?Rilevamento di "esecuzioni" di elementi DOM in jQuery

Per esempio, se ho il seguente elenco di voci

<ol> 
    <li class="a"></li> 
    <li class="foo"></li> 
    <li class="a"></li> 
    <li class="a"></li> 
    <li class="foo"></li> 
    <li class="foo"></li> 
    <li class="foo"></li> 
    <li class="a"></li> 
    <li class="foo"></li> 
    <li class="foo"></li> 
    <li class="foo"></li> 
</ol> 

dire che voglio prendere tutte le li.foo elementi e avvolgerli all'interno della propria <ol> blocco (o qualsiasi wrapper per quella materia) per finire con qualcosa di simile.

<ol> 
    <li class="a"></li> 
    <li class="foo"></li> 
    <li class="a"></li> 
    <li class="a"></li> 
    <li><ol> 
    <li class="foo"></li> 
    <li class="foo"></li> 
    <li class="foo"></li> 
    </ol></li> 
    <li class="a"></li> 
    <li><ol> 
    <li class="foo"></li> 
    <li class="foo"></li> 
    <li class="foo"></li> 
    </ol></li> 
</ol> 

Come si può vedere dall'esempio, voglio solo avvolgere "corre" di elementi li.foo Dom (dove ci sono 2 o più li.foo elementi in successione.

non sono sicuro del modo migliore/più efficace per ottenere questo risultato tramite jQuery (o JavaScript semplicemente per questo)

risposta

3

Esempio:http://jsfiddle.net/kNfxs/1/

$('ol .foo').each(function() { 
    var $th = $(this); 
    var nextUn = $th.nextUntil(':not(.foo)'); 
    if(!$th.prev('.foo').length && nextUn.length) 
     nextUn.andSelf().wrapAll('<li><ol></ol></li>'); 
}); 

Loop negli .foo elementi, e se l'elemento precedente non è .foo, ed ha almeno 1 .foo dopo, poi afferrare tutti i prossimi .foo elementi utilizzare il metodo nextUntil()(docs) e includere l'originale utilizzando il metodo andSelf()(docs), quindi avvolgerli utilizzando il metodo wrapAll()(docs).


Aggiornamento:Questo sarà un po 'più efficiente perché evita il metodo nextUntil()(docs) quando c'è un precedente .foo().

Esempio:http://jsfiddle.net/kNfxs/2/

$('ol .foo').each(function() { 
    var $th = $(this); 
    if($th.prev('.foo').length) return; // return if we're not first in the group 
    var nextUn = $th.nextUntil(':not(.foo)'); 
    if(nextUn.length) 
     nextUn.andSelf().wrapAll('<li><ol></ol></li>'); 
}); 
0

Usa qualcosa come questo:.

$(li).each(function(){ 
if($(this).next().hasClass('foo')){ 
---- Recursively check until the end of the run has been found ---- 
} 
}); 

per reçu controlla in modo accurato una funzione che controlli l'elemento successivo fino a quando non viene trovata la fine della corsa.

0

Non so quanto bene questo funziona per le prestazioni:

var $foo = $('.foo + .foo'); 
$foo.add($foo.prev()); 

$ pippo sarà il set di ".foo corre"

Edit per aggiungi:

ho pensato a un modo più semplice:

var $foo = $('.foo + .foo').prev('.foo').andSelf(); 
0

esempio di lavoro: http://jsfiddle.net/v8GY8/

Ai posteri:

// Takes a jQuery collection and returns an array of arrays of contiguous elems 
function groupContiguousElements($elems){ 
    var groups = []; 
    var current, lastElement; 
    $elems.each(function(){ 
    if ($(this).prev()[0] == lastElement){ 
     if (!current) groups.push(current=[lastElement]); 
     current.push(this); 
    }else{ 
     current = null; 
    } 
    lastElement = this; 
    }); 
    return groups; 
} 

var groups = groupContiguousElements($('li.foo')); 
$.each(groups, function(){ 
    var wrapper = $('<ol>').insertBefore(this[0]); 
    $.each(this,function(){ 
    wrapper.append(this); 
    }); 
}); 
Problemi correlati