1

每当我添加时,我都试图防止创建空文本节点

  • 换行符,
  • 空格(包括不间断空格)
  • 标签

到我的 HTML 结构。

例如。

<div><div>    <!-- Node not created -->
<div>
                <!-- Node created -->
<div>

例1。

<div><div>    <!-- Node not created -->
<div> <div>     <!-- Node created -->

例2。

<div><div>    <!-- Node not created -->
<div>            <!-- Node created -->
    <div>
                 <!-- Node created -->
    </div>    
<div>            <!-- Node created -->

在这里,为了更好地避免:看看第一个<DIV>s 会发生什么 - jsFiddle

4

3 回答 3

3

每次操作 DOM 时,调用node.normalize()父节点,它都会完成这项工作。

在Node.normalize中查看更多信息

更新

根据您提供的小提琴,我深入研究了这个问题,我根据您的 html 结构在 Chrome 29 中运行以下代码。

var i = 0;
function traverse(node){
    if (node.firstChild) {
        traverse(node.firstChild);
    }

    if (node.nodeType === 3) {
        console.log("text node " + ++i + ": " + node.nodeValue);
        if (node.nodeValue !== '') {
            console.log("text node " + i + " is not null");
        }
        if (node.nodeValue.match(/(\r\n|\r|\n)+/g)) {
            console.log("nonsense node");
        }
    }

    if (node.nextSibling) {
        traverse(node.nextSibling);
    }
}
document.addEventListener("DOMContentLoaded", doTraverse);

function doTraverse(){
    traverse(document.getElementsByClassName("selector")[0]);
}

并得到这些结果:

text node 1: 

text node 1 is not null
nonsense node
text node 2: 

text node 2 is not null 
nonsense node 
text node 3: 

text node 3 is not null 
nonsense node 
text node 4: 

text node 4 is not null 
nonsense node 
text node 5: 
            text

text node 5 is not null 
text node 6: a paragraph 
text node 6 is not null
text node 7: 

text node 7 is not null 
nonsense node 
text node 8: a paragraph 
text node 8 is not null 
text node 9: a paragraph 
text node 9 is not null 
text node 10: 
             more text

text node 10 is not null 
text node 11: 


text node 11 is not null 
nonsense node 

令我们惊讶的是,empty文本节点比我们预期的要多得多。但是,如果我们在 Chrome 的检查器中检查这些元素,一切似乎都正常。我猜 Chrome 在渲染引擎中优化了这个问题,但在 DOM 中没有。

我们有一个清晰的想法,那些empty文本节点实际上包含linebreaks,这使得您的代码无法按预期工作。所以如果你确实想删除那些文本节点,你可以遍历 DOM ,找到它们并删除它们(这将是非常低效的,我很欣赏更好的解决方案)。

顺便说一句,在这种情况下,node.normalize()它对您不起作用,因为它只是删除了真正的空文本节点。

于 2013-09-12T08:38:33.473 回答
1

如果您认为有必要,请添加评论

<ul>
  <li>one</li><!--
  --><li>two</li><!--
  --><li>three</li>
</ul>

这将使空白被注释掉并且不插入文本节点

来自http://css-tricks.com/fighting-the-space-between-inline-block-elements/

例如 1

<div><div><!-- 
--><div><!--

--><div>

例如 2

<div><div><!--
--><div><!-- --><div>

例如 3

<div><div><!--
--><div><!--
    --><div><!--

    --></div><!--    
--><div>  

使您的标记相当难看,但删除了文本节点

于 2013-09-12T08:38:49.463 回答
0

你可以在你的 DOM 上运行一个简单的清理函数:

function cleanNode(node) {
 var child;
 for (var i = node.childNodes.length; i--;) {
  child = node.childNodes[i];
  // If commentt/textNode and has no non-whitespace character in it, delete it.
  if (child.nodeType === 3 || child.nodeType === 8 && !/\S/.test(child.nodeValue)) {
   node.removeChild(child);
   n--;
  }
  else {
   cleanNode(child);
  } 
 }
}
于 2014-12-01T18:09:20.660 回答