2015-05-04 5 views
11

ho qualche HTML che assomiglia a questo:Come posso avvolgere i div bivoli contigui con un div genitore?

<p>Some Text</p> 
<div class="listBullet">Item 1</div> 
<div class="listBullet">Item 2</div> 
<div class="listBullet">Item 3</div> 
<p>Some More Text</p> 
<div class="listBullet">Item 1</div> 
<div class="listBullet">Item 2</div> 
<div class="listBullet">Item 3</div> 
<p>Some Other Text</p> 

Voglio finire con il seguente risultato:

<p>Some Text</p> 
<div class="wrapperDiv"> 
    <div class="listBullet">Item 1</div> 
    <div class="listBullet">Item 2</div> 
    <div class="listBullet">Item 3</div> 
</div> 
<p>Some More Text</p> 
<div class="wrapperDiv"> 
    <div class="listBullet">Item 1</div> 
    <div class="listBullet">Item 2</div> 
    <div class="listBullet">Item 3</div> 
</div> 
<p>Some Other Text</p> 

ho provato $(".listBullet").wrapAll("<div class='wrapperDiv' />"), ma che ha finito per spostare i due blocchi essere contiguo insieme. Sembra che quello di cui ho bisogno sia un selettore che separi i blocchi contigui in elementi separati, che poi chiamerei wrapAll separatamente.

risposta

14

Questo fa il lavoro:

$('p + .listBullet').each(function() { 
    $(this).nextUntil('p') 
     .addBack() 
     .wrapAll("<div class='wrapperDiv' />"); 
}); 

Fiddle 1


Se il Valid ha un mix di elementi, si può fare questo (supponendo container è la classe del genitore div):

$('.container > :not(.listBullet) + .listBullet').each(function() { 
    $(this).nextUntil('.container > :not(.listBullet)') 
     .addBack() 
     .wrapAll("<div class='wrapperDiv' />"); 
}); 

Fiddle 2


Ecco un approccio più forza bruta:

var lb= []; 
$('.container > *').each(function() { 
    if($(this).hasClass('listBullet')) { 
    lb.push(this); 
    } 
    else { 
    $(lb).wrapAll("<div class='wrapperDiv'/>"); 
    lb= []; 
    } 
}); 
$(lb).wrapAll("<div class='wrapperDiv'/>"); 

Fiddle 3

+0

Solo curioso, perché il '+' in '$ ('p + .listBullet')'? È diverso da '$ ('p .listBullet')'? –

+0

@JasonTowne è un selettore "fratello". L'intero problema dell'OP è che tutti gli elementi originali sono fratelli, con niente per raggruppare i 2 set di div. Se ci fossero, questo sarebbe banale. – Alnitak

+0

Quest'ultimo selezionerà '.listbullet' che è figlio di' p'. Il primo selezionerà '.listbullet' che è un fratello di' p' – Marquizzo

3

Come approccio generale si potrebbe:

ciclo tra tutti gli elementi della pagina utilizzando .next(), mentre l'elemento successivo a trovare si ha la classe corretta, (utilizzare .attr("class")) aggiungere una classe supplementare di currentList (o simular) class wrapAll su currentList quindi seleziona tutti gli elementi con la classe currentList e rimuovi quella classe e poi continua il ciclo!

+0

Sì, è lì che ero diretto ... stavo per vedere se ci fosse una scorciatoia. –

+0

Mi sono distrutto il cervello e non riuscivo a pensarne uno ... Potresti ovviamente scrivere una piccola funzione di libreria per fare esattamente ciò che potresti riciclare ogni volta che ne hai bisogno :-) #codeReuse – saml

2

Beh, si potrebbe anche fare qualcosa di simile, anche se forse solo con metodi di jQuery è più semplice (e un po 'più flessibile):

http://jsfiddle.net/ewj44a2L/1/

var listBullets = $('.listBullet'), 
 
    n = 3, // Number of bullets per group. All groups must be equal. 
 
    len = listBullets.length/n; // Number of groups to be encapsulated 
 
for(var i = 0; i < len; i++) { 
 
    listBullets.slice(n * i, n * (i + 1)) 
 
    .wrapAll('<div class="wrapperDiv"></div>'); 
 
}
.wrapperDiv { 
 
    background: #000; 
 
    color: #fff; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<p>Some Text</p> 
 
<div class="listBullet">Item 1</div> 
 
<div class="listBullet">Item 2</div> 
 
<div class="listBullet">Item 3</div> 
 
<p>Some More Text</p> 
 
<div class="listBullet">Item 1</div> 
 
<div class="listBullet">Item 2</div> 
 
<div class="listBullet">Item 3</div> 
 
<p>Some Other Text</p> 
 
<div class="listBullet">Item 1</div> 
 
<div class="listBullet">Item 2</div> 
 
<div class="listBullet">Item 3</div>

2

Prova

$("p").map(function(i, el) { 
 
    var el = $(el), list = ".listBullet"; 
 
    if (el.next().is(list)) { 
 
    var wrap = el.after("<div class=wrapperDiv />").next(); 
 
    do { wrap.next().appendTo(wrap); } 
 
    while (wrap.next().is(list)); 
 
    }; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> 
 
</script> 
 
<p>Some Text</p> 
 
    <div class="listBullet">Item 1</div> 
 
    <div class="listBullet">Item 2</div> 
 
    <div class="listBullet">Item 3</div> 
 
<p>Some More Text</p> 
 
    <div class="listBullet">Item 1</div> 
 
    <div class="listBullet">Item 2</div> 
 
    <div class="listBullet">Item 3</div> 
 
<p>Some Other Text</p>

Problemi correlati