如果我有这样的html:

<li id="listItem">
    This is some text
    <span id="firstSpan">First span text</span>
    <span id="secondSpan">Second span text</span>
</li>

我试图使用.text()检索字符串“这是一些文本”,但如果我说$('#list-item').text(),我得到“这是一些textFirst span textSecond span文本”。

是否有一种方法可以获取(并可能通过.text("")之类的方法删除)标签中的自由文本,而不是其子标签中的文本?

HTML不是我写的,所以这是我必须与工作。我知道这将是简单的,只是包装标签的文本时编写的html,但再次,html是预先编写的。


当前回答

这是一个老问题,但上面的答案效率很低。这里有一个更好的解决方案:

$.fn.myText = function() {
    var str = '';

    this.contents().each(function() {
        if (this.nodeType == 3) {
            str += this.textContent || this.innerText || '';
        }
    });

    return str;
};

然后这样做:

$("#foo").myText();

其他回答

只需将它放在<p>或<font>中,然后获取$('#listItem font').text()

我想到的第一件事

<li id="listItem">
    <font>This is some text</font>
    <span id="firstSpan">First span text</span>
    <span id="secondSpan">Second span text</span>
</li>

我认为这也将是一个很好的解决方案-如果你想获得所有文本节点的内容是选定元素的直接子。

$(selector).contents().filter(function(){ return this.nodeType == 3; }).text();

注意:jQuery文档使用类似的代码来解释内容函数:https://api.jquery.com/contents/

附注:还有一种更难看的方法,但这更深入地展示了事情是如何工作的,并允许在文本节点之间自定义分隔符(也许你想在那里换行)

$(selector).contents().filter(function(){ return this.nodeType == 3; }).map(function() { return this.nodeValue; }).toArray().join("");

对于初学者来说:

我更喜欢@都尊的答案,因为它简单易懂,比公认的答案更有效率。但它只部分适用于我,因为你不能直接传递元素与类选择器像这样

$(".landing-center .articlelanding_detail").get(0).immediateText() //gives .immediateText is not a function error

或者这个

$(".landing-center .articlelanding_detail")[0].immediateText() //gives .immediateText is not a function error

因为一旦你从$()函数中使用[index]或.get(index)提取了原生元素,你就失去了这里提到的jQuery对象方法的可链性。大多数解决方案只在id的上下文中使用,对于带有类选择器的元素多次使用不是很优雅。

所以,我写了jQuery插件:

$.fn.mainText = function(x=0) {
    return $.trim(this.eq(x).contents().not(this.eq(x).children()).text().replace(/[\t\n]+/g,' '));
};

这将返回元素的文本,而不管是否使用id或class作为排除子元素的选择器。也将删除任何\t或\n以获得一个干净的字符串。 像这样使用它:

案例1

$("#example").mainText(); // get the text of element with example id

案例2

$(".example").mainText(); // get the text of first element with example class

案例3

$(".example").mainText(1); // get the text of second element with example class and so on..

它需要是根据需求量身定制的,这取决于你所看到的结构。对于你提供的例子,这是有效的:

$(document).ready(function(){
     var $tmp = $('#listItem').children().remove();
     $('#listItem').text('').append($tmp);
});

演示:http://jquery.nodnod.net/cases/2385/run

但这取决于标记是否与你发布的内容相似。

类似于公认的答案,但没有克隆:

$("#foo").contents().not($("#foo").children()).text();

下面是一个jQuery插件用于此目的:

$.fn.immediateText = function() {
    return this.contents().not(this.children()).text();
};

下面是如何使用这个插件:

$("#foo").immediateText(); // get the text without children