2012-10-25 17 views
8

Ho un set nidificato di tag html e voglio eliminare tutti i tag e i relativi figli senza testo.jQuery rimuove in modo ricorsivo i bambini vuoti

Esempio:

<div id="mydiv"> 

<span></span> 
<span><br></span> 
<span> <span><br></span> </span> 
<span> <span><br> <span></span> </span> </span> 

<span> <img src="someimg.jpg" width="100" height="100"> </span> 
<span>some text</span> 

</div>​ 

quindi voglio campate con immagini e testo di rimanere e altri lasciano.

ho bisogno che il risultato dopo la mia funzione:

<div id="mydiv"> 

<span> <img src="someimg.jpg" width="100" height="100" /> </span> 
<span>some text</span> 
</div>​ 

ho capito, questo deve essere fatto in modo ricorsivo mediante JavaScript o jQuery con il suo metodo .children() ecco il mio codice che ho voluto usare, ma io non riesco a capire come costruire la ricorsione:

var remove_filter = function() { 
      children= $(this).children(); 

      for (var i = -1, l = children.length; ++i < l;) { 
       if ($(children[i]).text() == "") { 
        $(children[i]).remove(); 
       } 
       //may be recursion here 
       //else if(){ 
       //} 
      } 
      return $(this).text() == "" && $(this).children().length == 0; 
} 
$('#mydiv').find('span').filter(remove_filter).remove(); 

Questo codice è rotto, cancella e lascia campate vuote ... Come un io guadagno il mio risultato con la ricorsione?

CURA

Ecco la mia jsfiddle: http://jsfiddle.net/EGVQH/

modificato 2 volta

Ho trovato un bug nel la risposta giusta, ma è piccola. Se ho il codice come questo:

<div id="mydiv"> 
<span> <br> Some text</span> 
<span> <span><br> <span></span> </span> </span> 

<span> <img src="someimg.jpg" width="100" height="100"> </span> 
<span>some text</span> 

</div>​ 

suppongo che al risultato in:

<div id="mydiv"> 
<span> Some text</span> 
<span> <img src="someimg.jpg" width="100" height="100" /> </span> 
<span>some text</span> 
</div>​ 

precedente risposta "corretta" alla mia domanda stava dando risultato sbagliato a <span> <br> Some text</span>. Altre risposte erano sbagliate dopo aver provato un po '.

Vedi il mio JSfiddle: http://jsfiddle.net/EGVQH/2/

+0

ha a essere ricorsiva? – Aprillion

+0

penso che dovrebbe essere. perché il livello di nidificazione può essere di 10-20 elementi, quindi 20+ "per" cerchi sono cattivi :) – Feanor

+1

se un elemento non ha innerText, nessuno dei suoi figli ne ha, quindi dopo il test per le immagini il genitore superiore può essere rimosso in sicurezza senza controllare i bambini .. o cosa mi manca qui? – Aprillion

risposta

2
function rem(root) { 
    var $root = $(root); 
    $root.contents().each(function() { 
     if (this.nodeType === 1) { 
      rem(this); 
     } 
    }); 

    if (!$root.is("area,base,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr") && !$root.html().trim().length) { 
     $root.remove(); 
    } 
} 


rem("#mydiv");​ 

Utilizzando il:

<div id="mydiv"> 
<span> <br> Some text</span> 
<span> <span><br> <span></span> </span> </span> 

<span> <img src="someimg.jpg" width="100" height="100"> </span> 
<span>some text</span> 

</div>​ 

Foglie:

<div id="mydiv"> 
<span> Some text</span> 


<span> <img src="someimg.jpg" width="100" height="100"> </span> 
<span>some text</span> 

</div> 

http://jsfiddle.net/LEKaL/1/

+0

sembra essere più probabile. Lo testerò e poi accetterò domani se supererà i test. – Feanor

+0

@Feanor lo ha aggiornato, dovrebbe essere .contents() invece di .find. (la differenza è che il find probabilmente si bloccherà con una profondità maggiore: D) – Esailija

+0

grazie, userò la versione aggiornata – Feanor

1

Questo dovrebbe farlo. Ma questo rimuoverà anche l'immagine. È necessario aggiungere condizioni per non rimuovere l'immagine.

removeempty($('#mydiv')); 
function removeempty(parentnode){ 
var children=$(parentnode).children(); 
for(var i=0;i<children.length;i++){ 
    var text=$(children[i]).text(); 
    if($.trim(text).length==0){ 
     $(children[i]).remove(); 
    } 
    else{ 
     removeempty($(children[i])); 
    } 
} 
return; 
}​ 
2

Si può provare questo, senza ricorsione, utilizzando ogni, verificare la presenza di testo contenente tag non anche, come img

$(function(){ 
    $('#mydiv').find('span').each(function(){ 
     var self = $(this); 
     if($.trim(self.html())==""){ 
      self.remove(); 
     }else if($.trim(self.text())=="" && self.has('img').length ==0) 
      self.remove(); 
    }); 
}); 

è possibile modificare $(this).has('img').length ==0 per l'ingresso, iframe o in qualsiasi altro testo che contiene i tag come $(this).has('img, input, iframe').length ==0

+2

Dovresti usare $ .trim() invece di .trim() - si romperà in IE –

+0

@wirey, grazie per il tuo suggerimento, aggiornato. –

+0

grazie, questo funziona! :) – Feanor

1

Puoi utilizzare la funzione filtro per ottenere gli elementi necessari invece di cercare di trovare ciò che non ti serve.poi clonare e aggiungerli al tuo div

var x = $('#mydiv *').filter(function(){ 
    // return elements with a children of img or with some text 
    return $(this).children('img').length || $.trim($(this).text()).length ; 
}).clone(); 
$('#mydiv').html(x); 

http://jsfiddle.net/wirey00/5jymK/

2

Questo è un modo molto rapido e sporco di risolvere il tuo problema

$('#mydiv span br').remove(); 
while($('#mydiv span:empty').length > 0){ 
    $('#mydiv span:empty').remove(); 
} 
+0

il tuo esempio lascia vuote vuote. vedere qui http://jsfiddle.net/jccF3/ – Feanor

1
$.each($("#mydiv").find("span"),function(index,value){ 
    if($.trim($(value).html())) 
    { 
     $(value).remove(); 
    } 
}); 

E se si desidera rimuovere le pause , aggiungere questo prima di ogni affermazione:

$("#mydiv br").remove(); 
Problemi correlati