39

使用 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]*<

这可以在不使用正则表达式的情况下完成吗?

4

8 回答 8

62

我尝试了 user76888 提出的技术,效果很好。为了方便起见,我将它打包成一个 jQuery 插件,并认为社区可能会喜欢它,所以在这里:

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

要使用它,只需将其包含在脚本标签中,然后选择一个要使用 jQuery 清理的标签并调用函数,如下所示:

$('#widget').cleanWhitespace();
于 2010-04-06T18:38:18.870 回答
33

递归版本:

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;
}
于 2010-06-23T15:53:04.843 回答
21

我认为这会做到...

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);
 }
}
于 2009-10-08T19:43:46.057 回答
2

在将 HTML 设置为 DOM 节点后,您可能会做得更好。一旦浏览器解析了所有内容并从我们的标记中构建了一个 DOM 树,您就可以对找到的每个文本节点进行 DOM 遍历,如果它没有非空白字符,则将其完全删除,或者从一开始就修剪空白如果是,则结束。

于 2009-10-08T17:44:00.743 回答
2

这对我有用,也是一步一步的发现:

输出来自 chrome 控制台

首先定位包含讨厌空格的父节点

$('.controls label[class="radio"]').parent();

[<div class=​"controls">​
<label class=​"radio">​…​&lt;/label>​
" "
"    "
<label class=​"radio">​…​&lt;/label>​
" "
"    "
</div>​]

您可以看到它包含在 [] 括号中的数组中,即使找到单个项目,jQuery 也将始终返回类似数组的结构。

因此,要获取 HTMLElement,我们在索引 0 处获取数组中的第一项

$('.controls label[class="radio"]').parent()[0];

<div class=​"controls">​
<label class=​"radio">​…​&lt;/label>​
" "
"    "
<label class=​"radio">​…​&lt;/label>​
" "
"    "
</div>​

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

$('.controls label[class="radio"]').parent()[0].childNodes;

[<label class=​"radio">​…​&lt;/label>​, 
" ", 
"    ", 
<label class=​"radio">​…​&lt;/label>​, 
" ", 
"    "]

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

$($('.controls label[class="radio"]').parent()[0].childNodes);

[<label class=​"radio">​…​&lt;/label>​, 
" ", 
"    ", 
<label class=​"radio">​…​&lt;/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 因为我们看不到空白,所以我们用管道 | 填充它,好计划但是我们在这里有什么?如您所见,jQuery 无法将空格转换为 html,现在我们有未定义的。但这更好,因为空间可能是真实的未定义绝对是虚假的=)

因此,让我们摆脱 jQuery 的吸盘。我们需要的只是$(this).html() || $(this).remove();让我们看看:

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

[<label class=​"radio">​…​&lt;/label>​, 
" ", 
"    ", 
<label class=​"radio">​…​&lt;/label>​, 
" ", 
"    "]

哦,亲爱的..但不要害怕!每个仍然返回以前的结构而不是我们更改的结构,让我们看看我们的初始查询现在返回什么。

$('.controls label[class="radio"]').parent();

[<div class=​"controls">​
<label class=​"radio">​…​&lt;/label>​
<label class=​"radio">​…​&lt;/label>​
</div>​]

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

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

开心!

于 2012-09-18T16:02:12.577 回答
1

我不得不稍微修改接受的答案,因为由于某种原因,chrome 不想在空白节点上删除Child()。如果发生这种情况,您可以将节点替换为空文本节点,如本示例帮助函数中所示:

 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] );
      }
    }
  }

它需要一个您要从中删除空格的节点,并用一个真正空的文本节点递归地替换所有空格子节点。

于 2012-11-13T23:46:46.480 回答
0

采用

$($.parseHTML(widgetHTML, document, true)).filter("*"),
于 2014-10-28T16:26:59.260 回答
-3

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

于 2009-10-08T18:37:42.977 回答