2011-02-08 14 views
5

¿Cuál es la mejor forma de detectar ejecuciones de elementos dom en jQuery?Detección de "ejecuciones" de elementos DOM en jQuery

Por ejemplo, si tengo la siguiente lista de elementos

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

decir que quiero agarrar todos los li.foo elementos y se envuelven dentro de su propio <ol> bloque (o cualquier envoltorio para el caso) para terminar con algo así como

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

Como se puede ver en el ejemplo, sólo quiero envolver "corre" de los elementos li.foo dom (donde hay 2 o más li.foo elementos en la sucesión.

No estoy seguro de la mejor/manera más eficaz para lograr esto a través de jQuery (o Javascript simplemente para el caso)

Respuesta

3

Ejemplo: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>'); 
}); 

aro sobre el .foo elementos, y si el elemento anterior es no.foo, y tiene al menos 1 .foo después de que, a continuación, agarrar todos los próximos .foo elementos usando el método nextUntil()(docs) e incluye el original usando el método andSelf()(docs), luego envuélvelos usando el método wrapAll()(docs).


Actualización:Este será un poco más eficiente, ya que evita el método nextUntil()(docs) cuando hay una .foo() anterior.

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

usar algo como esto:.

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

para recu rsively check escribe una función que comprueba el siguiente elemento hasta que se encuentra el final de la ejecución.

0

No está seguro de lo bien que trabaja para el rendimiento:

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

$ foo será el conjunto de ".foo corre"

edición para agregar:

pensé en una forma más simple:

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

Ejemplo de trabajo: http://jsfiddle.net/v8GY8/

Para la posteridad:

// 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); 
    }); 
}); 
Cuestiones relacionadas