如果我有这样的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是预先编写的。


当前回答

对我来说,这似乎是一个过度使用jquery的例子。下面将抓取文本,忽略其他节点:

document.getElementById("listItem").childNodes[0];

你需要修剪它,但它能让你在一个简单的线条中得到你想要的。

EDIT

上面将获得文本节点。要得到实际的文本,使用这个:

document.getElementById("listItem").childNodes[0].nodeValue;

其他回答

就像问题一样,我试图提取文本,以便对文本进行一些正则表达式替换,但在我的内部元素(即:< I >, <div>, <span>等)也被删除的地方出现问题。

下面的代码似乎工作得很好,解决了我的所有问题。

它使用这里提供的一些答案,但特别地,只会在元素为nodeType === 3时替换文本。

$(el).contents().each(function() { 
  console.log(" > Content: %s [%s]", this, (this.nodeType === 3));

  if (this.nodeType === 3) {
    var text = this.textContent;
    console.log(" > Old   : '%s'", text);

    regex = new RegExp("\\[\\[" + rule + "\\.val\\]\\]", "g");
    text = text.replace(regex, value);

    regex = new RegExp("\\[\\[" + rule + "\\.act\\]\\]", "g");
    text = text.replace(regex, actual);

    console.log(" > New   : '%s'", text);
    this.textContent = text;
  }
});

上面所做的是遍历给定el的所有元素(它是通过$("div.my-class[name='some-name']"获得的);对于每个内部元素,它基本上都会忽略它们。对于文本的每个部分(由if (this。nodeType === 3),它将只对这些元素应用regex替换。

这。textContent = text部分只是替换替换的文本,在我的情况下,我正在寻找像[[min.val]], [[max.]]这样的标记。val]]等。

这段简短的代码摘录将帮助任何人试图做什么问题是问…再多一点。

对于初学者来说:

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

$(".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..

这是未经测试的,但我认为你可以尝试这样做:

 $('#listItem').not('span').text();

http://api.jquery.com/not/

只需将它放在<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>

使用简单的JavaScript在IE 9+兼容语法在短短几行:

const childNodes = document.querySelector('#listItem').childNodes;

if (childNodes.length > 0) {
    childNodesLoop:
    for (let i = 0; i < childNodes.length; i++) {
        //only target text nodes (nodeType of 3)
        if (childNodes[i].nodeType === 3) {
            //do not target any whitespace in the HTML
            if (childNodes[i].nodeValue.trim().length > 0) {
                childNodes[i].nodeValue = 'Replacement text';
                //optimized to break out of the loop once primary text node found
                break childNodesLoop;
            }
        }
    }
}