最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - How to get only directly contained text in DOM element in Javascript? - Stack Overflow

programmeradmin3浏览0评论

I have a div with some children within and its directly contained text like below:

<div id="price">
   100$
   <span>some ads</span>
   <span>another ads</span>
   for each
</div>

I want to get directly contained text '100$' in this DOM element.

I tried with innerHTML, innerText and textContent. But they show all text including children's text like below:

const element = document.getElementById('price');
console.log(element.innerText);
console.log(element.innerHTML);
console.log(element.textContent);
<div id="price">
   100$
   <span>some ads</span>
   <span>another ads</span>
   for each
</div>

I have a div with some children within and its directly contained text like below:

<div id="price">
   100$
   <span>some ads</span>
   <span>another ads</span>
   for each
</div>

I want to get directly contained text '100$' in this DOM element.

I tried with innerHTML, innerText and textContent. But they show all text including children's text like below:

const element = document.getElementById('price');
console.log(element.innerText);
console.log(element.innerHTML);
console.log(element.textContent);
<div id="price">
   100$
   <span>some ads</span>
   <span>another ads</span>
   for each
</div>

The expected result is 100$(I don't need "for each") which is directly contained text in parent element. So then I can get the price and its currency.

note: jquery is also allowed to use.

Share Improve this question edited Oct 5, 2021 at 15:24 isherwood 61.1k16 gold badges120 silver badges168 bronze badges asked Oct 1, 2019 at 15:05 DiamondDiamond 3,4284 gold badges20 silver badges41 bronze badges 7
  • This is a possible duplicate. See this question: stackoverflow.com/questions/3442394/… – Nico Griffioen Commented Oct 1, 2019 at 15:12
  • Possible duplicate of Using .text() to retrieve only text not nested in child tags – Heretic Monkey Commented Oct 1, 2019 at 15:12
  • I'm curious as to what is the real problem here. I think solving this with JS is a hack that hides the real problem. Can you not restructure the original markup to select only the desired text? – Marko Gresak Commented Oct 1, 2019 at 15:20
  • 1 Why isn't the expected result "100$ for each" that text is also directly contained by the div. Do you only want the first text? Is the HTML always structured this way with the first text? – skyline3000 Commented Oct 1, 2019 at 15:27
  • @Antonio now the question doesn't align with the expectation. According to the current markup, "directly contained text" would mean you want "100$ for each". – Marko Gresak Commented Oct 1, 2019 at 15:27
 |  Show 2 more comments

5 Answers 5

Reset to default 8

.clone() clones the selected element.

.children() selects the children from the cloned element

.remove() removes the previously selected children

.end() selects the selected element again

.text() gets the text from the element without children

const elementText = $("#price").clone()
                                .children()
                                .remove()
                                .end()
                                .text();

console.log(elementText.trim().split("\n")[0]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="parent">
  Parent
  <span>Child 1</span>
  <span>Child 2</span>
</div>

<div id="price">
   100$
   <span>some ads</span>
   <span>another ads</span>
   for each
</div>

EDIT: You can also use this:

$("#price").contents().get(0).nodeValue.trim()

Filter the childNodes to include only text nodes and use textContent of each of the matching nodes:

const text = Array.prototype.filter
    .call(element.childNodes, (child) => child.nodeType === Node.TEXT_NODE)
    .map((child) => child.textContent)
    .join('');

The text includes the full markup of the text, including newlines. If this is undesired, use text.trim().

The filter.call is used because childNodes is a NodeList, which is array-like, but does not support .filter method.


To get text only for the first node

const text = Array.prototype.filter
    .call(element.childNodes, (child) => child.nodeType === Node.TEXT_NODE)[0];

Alternatively, if you can rely on the fact that the value is always the first child, the above can be simplified to

const text = element.childNodes[0];

With jQuery :

const text = $($('#price').contents()[0]).text().trim();

You can do this using the "outerText" property. Like in the example below:

var text = document.querySelector('body').outerText;
var regex = /([\d]+)\$/g;
console.log(text.match(regex).join());
<div id="price">
   100$
   <span>some ads</span>
   <span>another ads</span>
   for each
</div>

HTMLElement.prototype.directText=function (){
  let el=this.cloneNode(true);
  while (el.children[0]) el.children[0].remove();
  return el.textContent;
}

So we can use:

let directText=document.getElementById('id').directText();
发布评论

评论列表(0)

  1. 暂无评论