The textContent and innerText Properties
18 04 2006In my original post, Using the innerText Property in Firefox, I wrote my example using document.all to determine when to use innerText or textContent.
Because the main purpose of that post was to explain to the reader that Firefox does not support the innerText property but the textContent property, I failed to consider other browsers… yes, shame on me! (thanks Paul for bringing this to my attention).
You see, there are browsers that although don’t support document.all, they DO support the innerText property: Safari and Konqueror.
So, it is more efficient to check if the innerText property is supported by the user agent (thanks, Matthias). The way I do it is like this:
var hasInnerText =
(document.getElementsByTagName("body")[0].innerText != undefined) ? true : false;
var elem = document.getElementById('id');
var elem2 = document.getElementById ('id2');
if(!hasInnerText){
elem.textContent = value;
elem2.textContent = value;
} else{
elem.innerText = value;
elem2.innerText = value;
}
Why am I using document.getElementsByTagName("body")[0]? Well, because, as you know, document.getElementsByTagName returns an array of elements with that tag name, and since there’s only ONE body tag, I’m calling the first and only index of that array at once. This is so, as you can see in the example above, if you have more than one element that you need to assign a value to.
I have an example. If you wish, check the source out to see how it works.
Compatibility:
- Linux:
- Konqueror 3.5.2
- Firefox 1.5.0.1
- Mac X:
- Safari 2.0.3
- Camino 1.0
- Windows:
- Firefox 1.5.0.2
- Opera 8.54
- Internet Explorer 6
- Internet Explorer 7.0.5346.5 Beta 2
Remember, this is one way to do it. Cheers!

















wicked !
thanks a lot
glad I can help
Thanks! I changed it for function use:
function changeTextById(elementId,changeVal){ var hasInnerText = (document.getElementsByTagName("body")[0].innerText != undefined) ? true : false; var elem = document.getElementById(elementId); if(!hasInnerText){ elem.textContent = changeVal; }else{ elem.innerText = changeVal; } }@Adam:
Thank you for your contribution! Just one little suggestion: What if we leave the innerText support checking outside the function? That way, the variable ‘hasInnerText’ will be a global one. Also, checking the innerText support will be done once and not everytime the function is called. So, a slight modified version of your function would be:
var hasInnerText = (document.getElementsByTagName("body")[0].innerText != undefined) ? true : false; function changeTextById(elementId,changeVal){ if(!hasInnerText){ elem.textContent = changeVal; }else{ elem.innerText = changeVal; } }That’s it.
Once again, thanks for your contribution!
Hey, thanks a lot, this post helped a whole load! Now if only I could figure out how to determine the width of a span tag when I haven’t assigned it one in css (it’s “fill out width” if you will) in IE, because apparently in every other browser it’s offset width. Oh well!
P.S. Love the naruto pic
What’s wrong with document.body?
@Ken,
It hasn’t been feelin’ well lately…
forgot the local var elem above…
var hasInnerText = (document.getElementsByTagName(”body”)[0].innerText != undefined) ? true : false; function changeTextById(elementId,changeVal){ var elem = document.getElementById(elementId); if(!hasInnerText){ elem.textContent = changeVal; }else{ elem.innerText = changeVal; } }there we go.
Great function! Thanks.
@Jesse,
Thanks much for catching that! **thumbs up**
Going further, I’d suggest the following changes:
1. Put the check for the innerText feature in a function
2. Change the elementId argument for changeTextById to just elem. This way you can also call the function from inside an iframe, for example. I think it makes the function more reusable.
3. Put the initialization of the hasInnerText global variable in a function and call the function from body onload. This ensures proper order.
4. Signify hasInnerText is a global variable somehow, such as using the g_ convention, making it g_hasInnerText
var g_hasInnerText = false; function checkForInnerTextFeature() { return (document.getElementsByTagName(”body”)[0].innerText != undefined) ? true : false; } function initialize() { g_hasInnerText = checkForInnerTextFeature(); } function changeText(elem,changeVal){ if(!g_hasInnerText){ elem.textContent = changeVal; }else{ elem.innerText = changeVal; } }usage:
or…
(Juan, if this is too far beyond the scope of this article, feel free to snip it out. These things just seem to be helpful, especially the part about proper order. That’s really what screwed me up. If you do, I’d suggest at least mentioning something about the proper order- when and where to do the one-time check for innerText/textContent support.)
hth,
Jesse
Jesse,
Excellent contribution! The code I post in my articles is simple. It’s just so that readers can have something to start with and take it from there, and that’s what you exactly did.
At a glance, I don’t really think you need the
initialize()function. As soon as I get home, I’ll take a better look at this and if I have any suggestions, I’ll let you know.Once again, your contribution is very much appreciated. **thumbs up**
Does innerHTML work on all the most significant browsers? (I guess this is relative, but…)
If so, then, for an all-in-one function, I’d propose to add an htmlFlag to the ChangeText function in the case you do want to render html:
function ChangeText(elem, changeVal, htmlFlag) { if(htmlFlag) { elem.innerHTML = changeVal; } else { if(!g_innerTextFeatureEnabledFlag) { elem.textContent = changeVal; } else { elem.innerText = changeVal; } } }If innerHTML does not have broad enough support, what would be a good alternative?
argh. I accidentally capitalized the function. my bad. It should be called changeText.
Anyway, so the usage for the above version of changeText would be:
or…
Jesse,
I tested your code and it didn’t work for me. The
g_hasInnerTextnever got set to either true or false by thecheckForInnerTextFeature()function, and because of that, its original value, when the variable was decleared and initialized, never changed fromfalse. Therefore I have the following suggestions:In your example you don’t need to have a global variable, and you don’t need to have the
initialize()function.BTW, I always capitalize my functions (i.e. ChangeText()), but that’s me.
Going back to my observations and suggestions, I would suggest you’d write your functions like so:
function checkForInnerTextFeature() { var obj = (document.getElementsByTagName("body")[0].innerText != undefined) ? true : false; return obj; } function changeText(elem,changeVal){ if(!checkForInnerTextFeature()){ elem.textContent = changeVal; }else{ elem.innerText = changeVal; } }See, you have one function and one variable less. You don’t even need to call the
checkForInnerTextFeature()function on anonloadevent, there’s no need for that. You can call it whenever you call thechangeText()function and the rest of the code will execute accordingly. Other than that your code looks nice.BTW, innerText is not a feature, is a property, so I’d suggest also to change the name of your function to
CheckForInnerTextProperty()or something similar.Alternatively
function changeText(elem,changeVal){
if(elem.textContent){
elem.textContent = changeVal;
}else{
elem.innerText = changeVal;
}
}
or if you want you can test for innerText . It is recomended that you check for the availability of a property of a method this way.
Dharshana,
You said: “It is recomended that you check for the availability of a property of a method this way”.
I don’t quiet understand why it’s ‘recommended’ the way you put it. To me, it’s just another way to check for the property support. Besides the ‘amount’ of code used, it’s not so different from doing it like in my example (or the use of a function for that matter):
var hasInnerText = (document.getElementsByTagName("body")[0].innerText != undefined) ? true : false;why you need to check the innerText property on the body element and not the dom element getting called?
function changeTextById(elm, value){
if (elm instanceof “string”) {
elm = document.getElementById(elm);
}
if (elm.textContent) {
elm.textContent = value;
}else{
elm.innerText = value;
}
}
isn’t that enough
delphi329,
The answer to your question is right there in the article. Read it again and you’ll find it.
Basically, it all depends on what you need to do. If you’re gonna affect one element only, sure, they way you put it should work fine.
The problem with textContent is that it doesn’t get posted back to a form (in ASP.net) whereas innerText does. I thought Firefox was supposed to be the answer to the ghastly compatibility issues of old, but I see it’s still alive and kicking. Shame.
Alex,
Well, perhaps this happens because ASP.Net and innerText are Microsoft’s.
innerTextis a proprietary MSIE attribute, go figure.What about “firstChild.nodeValue” that seems to work in both IE and Firefox (instead of “innerText”/”textContent”) ?
BB
[...] See also: The textContent and innerText Properties. This post will help you to make the innerText property work in Safari [...]
thanks Benoît Bruet you saved my butt, nodeValue works great
so much simpler than messing around with innerHTML/textContent
@ Benoît Bruet
I tested obj.firstChild.nodeValue in IE (5.5, 6, 7), Opera and Firefox and only IE 5.5 doesnt support nodeValue property, thus making it the most reliable innerText replacement.
Thanks Juan Wong for this article.
Thank you, Efficent Tips!
nice write-up. Thanks!