使用jQuery删除HTML元素之间的空格和换行符

使用jQuery,我想删除HTML标签之间的空白和换行符。

var widgetHTML = ' <div id="widget"> <h2>Widget</h2><p>Hi.</p> </div>'; 

应该:

 alert(widgetHTML); // <div id="widget"><h2>Widget</h2><p>Hi.</p></div> 

我认为我需要的模式是:

 >[\s]*< 

这可以完成而不使用正则expression式?

我尝试了user76888布置的技术,它运行得很好。 为了方便,我把它打包成一个jQuery插件,并认为社区可能会喜欢它,所以在这里:

 jQuery.fn.cleanWhitespace = function() { this.contents().filter( function() { return (this.nodeType == 3 && !/\S/.test(this.nodeValue)); }) .remove(); return this; } 

要使用它,只需将其包含在脚本标记中,然后select一个标记以使用jQuery进行清理,然后像这样调用该函数:

 $('#widget').cleanWhitespace(); 

recursion版本:

 jQuery.fn.htmlClean = function() { this.contents().filter(function() { if (this.nodeType != 3) { $(this).htmlClean(); return false; } else { this.textContent = $.trim(this.textContent); return !/\S/.test(this.nodeValue); } }).remove(); return this; } 

我认为这会做到这一点…

 cleanWhitespace: function(element) { element = $(element); for (var i = 0; i < element.childNodes.length; i++) { var node = element.childNodes[i]; if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) Element.remove(node); } } 

将HTML设置为DOM节点后,您可能会做得更好。 一旦浏览器parsing了所有内容并从我们的标记中构build了一个DOM树,就可以执行DOM遍历,并且对于find的每个文本节点,如果它没有非空白字符,或者从开始修剪空白字符如果它结束的话。

这是对我和逐步发现的工作:

输出来自chrome控制台

首先定位包含令人讨厌的空白的父节点

 $('.controls label[class="radio"]').parent(); [<div class=​"controls">​ <label class=​"radio">​…​</label>​ " " " " <label class=​"radio">​…​</label>​ " " " " </div>​] 

你可以看到这是从[]括号中包装一个数组jQuery将总是返回一个类似结构的数组,即使find一个单一的项目。

所以要到达HTMLElement,我们把数组中的第一个项目放在索引0处

 $('.controls label[class="radio"]').parent()[0]; <div class=​"controls">​ <label class=​"radio">​…​</label>​ " " " " <label class=​"radio">​…​</label>​ " " " " </div>​ 

注意如何不再有[]括号。 我们需要这样做的原因是因为jQuery将忽略dom中的空白,但HTMLElement不会,看看当我们访问childNodes属性时会发生什么

 $('.controls label[class="radio"]').parent()[0].childNodes; [<label class=​"radio">​…​</label>​, " ", " ", <label class=​"radio">​…​</label>​, " ", " "] 

我们有一个数组,是的,你发现[]括号,但你看到另一个区别,看看所有的逗号,我们不能用jQuery得到。 谢谢HTMLElement,但现在我们可以回到jQuery,因为我想用each代替for循环,你同意我吗? 所以让我们在jQuery中包装数组,看看会发生什么:

 $($('.controls label[class="radio"]').parent()[0].childNodes); [<label class=​"radio">​…​</label>​, " ", " ", <label class=​"radio">​…​</label>​, " ", " "] 

完善! 我们有完全相同的结构,但在一个jQuery对象内部,所以让我们打电话给每个打印“this”来看看我们有什么。

 $($('.controls label[class="radio"]').parent()[0].childNodes).each(function () { console.log('|'+$(this).html()+'|'); }); |<input id="gender_f" name="gender" type="radio" value="f">Female| |undefined| |undefined| |<input id="gender_m" name="gender" type="radio" value="m" checked="">Male| |undefined| |undefined| 

所以我们使用jQuery来获取每个元素的html,标准的东西`$(this).html,因为我们不能看到空白的空间让我们用pipe道来填充它,好的计划,但是我们在这里有什么? 正如你所看到的,jQuery不能将空白转换为html,现在我们还没有定义。 但是,这更好,因为一个空间可能会成为truthy未定义肯定是falsy =)

所以让我们摆脱与jQuery的吸盘。 我们需要的是$(this).html() || $(this).remove(); $(this).html() || $(this).remove(); 让我们来看看:

 $($('.controls label[class="radio"]').parent()[0].childNodes).each(function () { $(this).html() || $(this).remove(); }); [<label class=​"radio">​…​</label>​, " ", " ", <label class=​"radio">​…​</label>​, " ", " "] 

哦,亲爱的,但不要害怕! 每个仍然返回以前的结构,而不是我们已经改变的结构,让我们看看我们现在最初的查询返回。

 $('.controls label[class="radio"]').parent(); [<div class=​"controls">​ <label class=​"radio">​…​</label>​ <label class=​"radio">​…​</label>​ </div>​] 

和瓦拉! 所有性感和漂亮=)

所以你有它,如何删除元素/标签ala jQuery风格之间的空白。

的nJoy!

我不得不稍微修改接受的答案,因为由于某种原因,chrome不想在空白节点上删除Child()。 如果发生这种情况,你可以像这个例子中的helper函数那样用一个空的文本节点replace节点:

  var removeWhiteSpaceNodes = function ( parent ) { var nodes = parent.childNodes; for( var i =0, l = nodes.length; i < l; i++ ){ if( nodes[i] && nodes[i].nodeType == 3 && !/\S/.test( nodes[i].nodeValue ) ){ parent.replaceChild( document.createTextNode(''), nodes[i] ); }else if( nodes[i] ){ removeWhiteSpaceNodes( nodes[i] ); } } } 

它需要一个从中删除空白的节点,并recursion地用一个真正的空文本节点replace所有的空白子节点。

使用

 $($.parseHTML(widgetHTML, document, true)).filter("*"), 

你可以$.trim(widgetHTML); 读取周围的空白。