Is there a way to get innerText of only the top element (and ignore the child element's innerText)?
18,082
Solution 1
Just iterate over the child nodes and concatenate text nodes:
var el = document.getElementById("your_element_id"),
child = el.firstChild,
texts = [];
while (child) {
if (child.nodeType == 3) {
texts.push(child.data);
}
child = child.nextSibling;
}
var text = texts.join("");
Solution 2
This will work in your example:
document.getElementById("item").firstChild.nodeValue;
Note: Keep in mind that this will work if you know you are dealing with that specific HTML. If your HTML can change, for example to:
<div>
<div class="item"> child node text </div>
top node text
</div>
then you should use the more generic solution by @Tim Down
Here is working code snippet:
window.onload = function() {
var text = document.getElementById("item").firstChild.nodeValue;
document.getElementById("result").innerText = text.trim();
};
#result {
border: 1px solid red;
}
<div id="item">
top node text
<div> child node text </div>
</div>
<strong>Result:</strong> <div id="result"></div>
Solution 3
- Clone the element.
- Loop through all child nodes (backwards, to avoid conflicts):
If the element has atagName
attribute, then it's an element: Remove the node. - Use
innerText
to get the textual contents (with fallback totextContent
, wheninnerText
is not supported).
Code:
var elem = document.getElementById('theelement');
elem = elem.cloneNode(true);
for (var i=elem.childNodes.length-1; i>=0; i--) {
if (elem.childNodes[i].tagName) elem.removeChild(elem.childNodes[i]);
}
var innerText = elem['innerText' in elem ? 'innerText' : 'textContent'];
Solution 4
function getDirectInnerText(element) {
var childNodes = element.childNodes;
result = '';
for (var i = 0; i < childNodes.length; i++) {
if(childNodes[i].nodeType == 3) {
result += childNodes[i].data;
}
}
return result;
}
element = document.querySelector("div#element");
console.log(getDirectInnerText(element))
<div id="element">
top node text
<div> child node text </div>
</div>
Related videos on Youtube
Author by
ivymike
Updated on June 04, 2022Comments
-
ivymike over 1 year
Is there a way to get innerText of only the top element (and ignore the child element's innerText) ?
Example:
<div> top node text <div> child node text </div> </div>
How to get the "top node text" while ignoring "child node text" ? innerText property of top div seem to return concatenation of both inner , top text.
-
Oded over 11 yearsRemove the non text direct child nodes first?
-
Tim Down over 11 years@Oded: No need. Just iterate over the children and concatenate. Easy peasy.
-
-
ivymike over 11 yearsWow, works like charm in all browsers. Frankly, I didn't think it was possible before posting the question :) ... thank you...
-
Tim Down over 11 yearsNo need to clone or mutate the DOM at all. Just read the text node children. See my answer.
-
Daniel Earwicker over 11 years+1 Clearly better than cloning what may be a very large bit of DOM tree, just to discard most of it. Only improvement would be
text = []
at the start, and thentext.push(child.data)
per iteration, and finallytext = text.join('')
at the end to turn the array of pieces into a string, which tends to be faster than repeated concatenations to an ever-growing string. -
Tim Down over 11 years@DanielEarwicker: I considered that, but I think the last benchmarks I saw suggested it was not clear cut that it actually improves performance so I went for the simpler version. I'll check now.
-
Rob W over 11 yearsNice one. PS.
data
is the defined in theCharacterData
interface, which is implemented byText
(text nodes). -
Rob W over 11 years@ivymike Tims's method is better. I suggest to accept his answer instead of mine. It also works in all browsers (tested in IE6+, Chrome 1+, Safari 5, Firefox 3+).
-
Tim Down over 11 years@DanielEarwicker: Seems as though array join may well be slower in modern browsers but is way quicker in IE 7, which trumps everything since your slowest target browser is where you actually need performance gains. Amending...
-
William Ardila over 6 yearsInstead 3 you can use Node.TEXT_NODE Source (See named constants)
-
Tim Down over 6 years@WilliamArdila: True. It was true in 2012 except for IE <= 8, which hadn't gone away by that point.
-
Tom about 6 yearsAm I missing something, or is this the opposite of what they're asking for?