How can I get text from a node so that it returns it with whitespace formatting like "innerText" does, but excludes descendant nodes that are hidden (style display:none)?
UPDATE: As the OP points out in comments below, even though MDN clearly states that IE introduced innerText
to exclude hidden content, testing in IE indicates that is not the case. To summarize:
innerText
returns text only from visible elements.innerText
returns all text, regardless of the element's visibility.innerText
is undefined (as indicated by the W3C, and in my testing).Add all of this up, and you have a property to avoid like the plague. Read on for the solution....
If you want cross-browser compatibility, you'll have to roll your own function. Here's one that works well:
function getVisibleText( node ) {
if( node.nodeType === Node.TEXT_NODE ) return node.textContent;
var style = getComputedStyle( node );
if( style && style.display === 'none' ) return '';
var text = '';
for( var i=0; i<node.childNodes.length; i++ )
text += getVisibleText( node.childNodes[i] );
return text;
}
If you want to get painfully clever, you can create a property on the Node
object so that this feels more "natural". At first I thought this would be a clever way to polyfill the innerText
property on Firefox, but that property is not created as a property on the Node
object prototype, so you would really be playing with fire there. However, you can create a new property, say textContentVisible
:
Object.defineProperty( Node.prototype, 'textContentVisible', {
get: function() {
return getVisibleText( this );
},
enumerable: true
});
Here's a JsFiddle demonstrating these techniques: http://jsfiddle.net/8S82d/
This is interesting, I came here because I was looking for why the text of display:none
elements was omitted in Chrome.
So, this was ultimately my solution.
Basically, I clone the node and remove the classes/styling that set display:none
.
innerText
function getInnerText(selector) {
let d = document.createElement('div')
d.innerHTML = document.querySelector(selector).innerHTML.replaceAll(' class="hidden"', '')
return d.innerText
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With