如何使用jQuery从父元素中删除文本(而不删除内部元素)

22

想象一下,我有以下内容(修改自 http://viralpatel.net/blogs/jquery-get-text-element-without-child-element/):

<div id="foo">
    first
    <div id="bar1">
        jumps over a lazy dog!
    </div>
    second
    <div id="bar2">
        another jumps over a lazy dog!
    </div>
    third
</div>

如何在不影响任何子元素的情况下,仅从DOM中删除“first”、“second”和“third”文本?

https://dev59.com/ynE85IYBdhLWcg3wkkU8 or https://dev59.com/dnA75IYBdhLWcg3wKlqM - kannix
这里有一个回答,解决了如何使用jQuery选择不在元素内的文本的问题:https://dev59.com/oVjUa4cB1Zd3GeqPQluI - fan711
所有链接问题中的答案要么完全错误,要么会导致不必要的问题,例如丢失事件处理程序,或在某些浏览器中出现错误(例如使用nodeType常量)。 - James Allardice
4个回答

32

如果您想删除所有子文本节点,可以使用.contents()然后使用.filter()将匹配集减少到仅包含文本节点:

$("#foo").contents().filter(function () {
     return this.nodeType === 3; 
}).remove();​​​​​​​

这里有一个可运行的示例

注意:这将保留子元素上的所有现有事件处理程序,而使用.html()的答案不会这样做(因为元素从DOM中删除并重新添加)。

注意2:在一些链接的问题的答案中显示类似于我在这里回答的代码,但它们使用nodeType常量(例如return this.nodeType === Node.TEXT_NODE)。这是不好的实践,因为IE版本低于9不实现Node属性。使用整数更安全(可以在DOM level 2规范中找到)。


可怕的 .html 解决方案在这种情况下不会删除处理程序(或者也许会?),但这只是偶然发生的,因为 .html 也可以插入节点(虽然未记录)。编辑:好吧,他们肯定会删除处理程序,因为 .html 中隐含了 .empty() - Esailija
@Esailija - 使用mgraph答案中的代码似乎会删除事件处理程序:http://jsfiddle.net/jamesallardice/PXxC4/1/ - James Allardice
那么数字3实际上是指什么?查看DOM Level 2规范,我没有看到以任何数字列出节点类型。我很好奇 :) - Jamie Hutber
@JamieHutber - 它们是用数字列出的。请参见此部分。看起来我的链接出了问题,所以它链接到文档的其他随机部分。 - James Allardice
哇,太棒了,谢谢。这是一种非常有趣的处理元素的方式。我肯定会寻找可以使用它的方法。谢谢。 - Jamie Hutber
2
如果您在浏览器(尤其是 WebKit)中遇到 ILLEGAL 错误,则请查看此问题的被接受答案以获取解决方案:https://dev59.com/K2855IYBdhLWcg3wVist - Serj Sagan

13

这里是一个无需使用jQuery的版本,可以在所有主要浏览器中运行,甚至包括IE 5,仅仅是为了展示没有jQuery也不用惊慌失措。

演示:http://jsfiddle.net/timdown/aHW9J/

代码:

var el = document.getElementById("foo"), child = el.firstChild, nextChild;

while (child) {
    nextChild = child.nextSibling;
    if (child.nodeType == 3) {
        el.removeChild(child);
    }
    child = nextChild;
}

@JamieHutber:别担心,一切都会好的。 - Tim Down

7

4
您可以使用这个。
$("#foo").html($("#foo").children());​

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接