【问题标题】:removing all text nodes from a particular div tag using javascript使用 javascript 从特定 div 标签中删除所有文本节点
【发布时间】:2011-09-22 06:46:14
【问题描述】:

我有一些从 php 脚本动态生成的 html。 php代码是这样的

echo "<div id='categories'>\n";
foreach($category as $k => $v)
{
echo "<div class='category'>\n";
echo "<div id=\"$k\" class='cat_name'\n>$k</div>\n";
echo "<div id=\"$k".'_link"'." class='cat_link'>\n<a href=$v>Link</a>\n</div>\n";
echo "</div>\n";
}
echo "</div>\n";

我有一个 javascript 文件尝试像这样访问 dom

var categories=document.getElementById('categories').childNodes;
for(i=0;i<categories.length;i++)
{
var link=categories[i].childNodes[1].childNodes[0].attributes['href'];
..
...
..

现在这不能按预期工作,因为 html 中有文本节点。 当我使用firebug console 尝试这个时

document.getElementById('categories').childNodes[0].nodeType; // displays 3 

它显示3,这意味着该节点是text node。 我尝试像这样在window.onload 中添加document.normalize();

window.onload=function() {
document.normalize();
var categories=document.getElementById('categories').childNodes;
...
...

但文本节点仍保留在 html 中。我怎样才能删除所有的文本节点。现在我认为没有像getElementByType() 这样的方法,那么我如何获取所有文本节点。

【问题讨论】:

    标签: javascript html dom textnode


    【解决方案1】:

    EE2015 语法:

    var elm = document.querySelector('ul');
    
    console.log(elm.outerHTML);
    
    // remove all text nodes
    [...this.elm.childNodes].forEach(elm => elm.nodeType != 1 && elm.parentNode.removeChild(elm))
    
    console.log(elm.outerHTML);
    <ul>
      <li>1</li>
      a
      <li>2</li>
      b
      <li>3</li>
    </ul>

    细分:

    1. 获取所有孩子
    2. 将 HTMLCollection 转换为数组
    3. 遍历数组并检查每个项目是否属于 文本节点
    4. 如果是,请从 DOM 中删除该项目

    这只会删除直接子文本节点,不会删除树中的任何内容。


    NodeIterator:

    var elm = document.querySelector('ul')
    
    // print HTML BEFORE removing text nodes
    console.log(elm.outerHTML)
    
    // remove all text nodes
    var iter = document.createNodeIterator(elm, NodeFilter.SHOW_TEXT)
    var node;
    while (node = iter.nextNode()) {
        node.parentNode.removeChild(node)
    }
    
    // print HTML AFTER removing text nodes
    console.log(elm.outerHTML)
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3<span>4</span></li>
    </ul>

    【讨论】:

      【解决方案2】:

      仅使用.children 而不是.childNodes 来定位元素(无文本节点):

         // --------------------------------------------------v
      var categories=document.getElementById('categories').children;
      

      FF3 不支持该属性,因此如果您支持该浏览器,则需要一种方法来复制它。

      function children( parent ) {
          var node = parent.firstChild;
          var result = [];
          if( node ) {
              do {
                  if( node.nodeType === 1 ) {
                      result.push( node );
                  }
              } while( node = node.nextSibling )
          }
          return result;
      }
      var parent = document.getElementById('categories');
      var categories= parent.children || children( parent );
      

      还要注意,IE 也会给你评论节点,所以如果你的标记不包含 cmets 会更好。

      【讨论】:

        【解决方案3】:

        检查循环中的每个节点,如果它是文本节点,则按照您所说的将其删除或不执行任何操作。如果它不是文本节点,请执行您想要对其执行的操作。

        【讨论】:

          【解决方案4】:

          你为什么不改用getElementsByClassName MDC docs

          var categories=document.getElementByClassName('category');
          

          对于本身不支持它的浏览器,请查看以下实现:http://ejohn.org/blog/getelementsbyclassname-speed-comparison/

          【讨论】:

          • 这不能解决我的问题。我的 html 上到处都是文本节点。我需要删除那些文本节点以便进一步遍历
          • @lovesh,那么你应该使用answer of patrick dw
          猜你喜欢
          • 2022-08-19
          • 1970-01-01
          • 2022-08-08
          • 1970-01-01
          • 1970-01-01
          • 2022-11-16
          • 2018-02-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多