2012-10-25 50 views
8

我有一个嵌套的html标签集,我想删除所有标签和他们的孩子没有文字。jQuery递归删除空的子女

例子:

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

所以我想用图片和文字跨度留下来,其他人离开。

我需要我的功能后的结果:

<div id="mydiv"> 

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

我想通了,这是要或者通过JavaScript,或者与它的方法。孩子的jQuery() 这里完成递归是我的代码想用,但我想不出如何建立递归:

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

这段代码被打破,它会删除并留下空跨度... 的我如何获得我的递归结果呢?

EDITED

这里是我的jsfiddle:http://jsfiddle.net/EGVQH/

组织编写了时间

我找到了正确的答案错误,但它是小的。如果我有这样的代码:

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

我认为它会导致:

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

以前的“正确”回答我的问题在<span> <br> Some text</span>给出错误的结果。其他答案在测试一下后是错误的。

见我的jsfiddle:http://jsfiddle.net/EGVQH/2/

+0

它必须是递归的? – Aprillion

+0

我认为应该是。因为嵌套层次可能高达10-20个元素,所以20+“for”圆圈不好:) – Feanor

+1

如果一个元素没有innerText,它的子元素都没有,所以在测试图像之后,顶层父元素可以是没有检查孩子安全地移除..或我在这里失踪? – Aprillion

回答

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");​ 

使用上:

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

叶:

<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

似乎更有可能。如果通过测试,我会测试它,然后明天再接受。 – Feanor

+0

@Feanor已更新它,它应该是.contents()而不是.find。 (不同的是,发现可能会崩溃更深入:D) – Esailija

+0

谢谢你,我会用更新的版本 – Feanor

1

这应该这样做。但是这也会删除图片。您需要添加条件才能删除图像。

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

你可以试试这个,不递归,使用每个,检查非包含标记文字也一样,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(); 
    }); 
}); 

您可以输入,iframe或含标签的任何其他非文本改变$(this).has('img').length ==0$(this).has('img, input, iframe').length ==0

+2

您应该使用$ .trim()而不是.trim() - 它会在IE –

+0

@wirey中断,感谢您的建议,并已更新。 –

+0

谢谢,这个工程!:) – Feanor

1

您可以使用过滤功能来获取所需的元素,而不是试图找到你不需要的东西。然后克隆,并将它们添加到您的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

这是解决你的问题

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

你的例子留下空的跨度。看到这里http://jsfiddle.net/jccF3/ – Feanor

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

的一个非常快速和肮脏的方式,如果你想删除的断裂,在每条语句前加上:

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