3

我正在尝试从节点中删除所有子元素,但保留节点的实际文本内容。即从此:

<h3>
   MY TEXT
   <a href='...'>Link</a>
   <a href='...'>Link</a>
   <select>
      <option>Value</option>
      <option>Value</option>
   </select>
</h3>

对此:

<h3>
   MY TEXT
</h3>

我知道在 jQuery 中有一百万种简单的方法可以做到这一点,但这不是这个项目的选择......我必须使用普通的旧 javascript

这:

var obj = document.getElementById("myID");
if ( obj.hasChildNodes() ){
    while ( obj.childNodes){
        obj.removeChild( obj.firstChild );       
    }
}

显然结果只是<h3></h3>,当我尝试时:

var h3 = content_block.getElementsByTagName('h3')[0];
var h3_children = h3.getElementsByTagName('*');
for(var i=0;i<h3_children.length;i++){
   h3_children[i].parentNode.removeChild(h3_children[i]);
}

它在中途挂断。我认为删除选项有问题,但是改变for循环以跳过删除,除非h3_children[i].parentNode==h3(即仅删除第一级子元素)在删除第一个<a>元素后停止。

我确定我在这里遗漏了一些非常明显的东西,但也许是时候转向人群了。如何删除所有子元素但不保留第一级textNodes?为什么上述方法不起作用?

编辑

发布了几个可行的解决方案,这很棒,但我仍然对为什么循环和删除h3.getElementsByTagName('*')不起作用感到有些困惑。类似的方法(改编自Blender)同样不能完成删除子节点的过程。关于为什么会这样的任何想法?

4

5 回答 5

3
var h3=content_block.getElementsByTagName("h3")[0];
for(var i=0;i<h3.childNodes.length;i++)
{
  if(h3.childNodes[i].nodeType==3)//TEXT_NODE
  {
    continue;
  }
  else
  {
    h3.removeChild(h3.childNodes[i]);
    i--;
  }
}

JSFiddle 演示

编辑

结合i--使其看起来更短:

var h3=content_block.getElementsByTagName("h3")[0];
for(var i=0;i<h3.childNodes.length;i++)
{
  if(h3.childNodes[i].nodeType==3)//TEXT_NODE
    continue;
  else
    h3.removeChild(h3.childNodes[i--]);
}

编辑#2:

@SomeGuy 指出,让它更短:

var h3=content_block.getElementsByTagName("h3")[0];
for(var i=0;i<h3.childNodes.length;i++)
{
  if(h3.childNodes[i].nodeType!=3)//not TEXT_NODE
    h3.removeChild(h3.childNodes[i--]);
}

括号也可以删除,但这会“不那么可读”和“令人困惑”,所以我把它放在那里。

于 2012-10-19T05:50:26.820 回答
1

您可以检查属性.nodeType.nodeName每个节点。

文本节点将这些属性设置为:

.nodeType == 3
.nodeName == '#text'`
于 2012-10-19T05:54:45.883 回答
1

例如:

var e = obj.firstChild
while (e) {
   if (e.nodeType == 3) {
      e = e.nextSibling
   } else {
      var n = e.nextSibling
      obj.removeChild(e)
      e = n
   }
}
于 2012-10-19T05:57:51.027 回答
1

试试这个。我假设你会在这里保留蚂蚁文本。

var h3 = document.getElementsByTagName('h3')[0];

if (h3.hasChildNodes()) {
    for (var i = h3.childNodes.length - 1; i >= 0; i--) {
        if (h3.childNodes[i].nodeName != "#text")
            h3.removeChild(h3.childNodes[i]);
    }
}

希望它会奏效。

于 2012-10-19T06:02:36.037 回答
0

好吧,我使用的东西(灵感来自这里的答案)有点像:

   var h3 = document.getElementsByTagName("h3")[0];
    Array.protoype.filter.call(h3.childNodes, function(child){
        if (child.nodeType != 3) {
            h3.removeChild(child);
        }
    });
于 2014-11-06T10:00:13.833 回答