JavaScriptにおいて、ある特定エレメントのテキスト部分を取り出すプロパティとして、「textContent」「innerText」があります。
前者はW3Cで規定されている標準のプロパティ、後者はInternet Explorer独自の拡張機能です。

これらが全く同じ動作をするのか、といえばそうではなく、その挙動でハマったのでメモ。
いやー、XMLの仕様まで読むことになるとは思っていませんでした……。

実現したかったことは、ブログテンプレート作成の際なのですが、その要素の内容が空(ここで言う空、というのは、スペース・タブ・改行文字コード以外のものが一切ないこと)の場合に、JavaScriptで「display: none」処理してやる、というものです。

まずは各プロパティの定義。

*innerText

the text between the start and end tags.


innerText property。MSDN

innerText の方は「タグの間にあるテキストを取得する」と、いたってシンプルですね。


*textContent

このアトリビュートはこのノードと子孫のテキスト内容を返す。それがnullであると定義されている時、その設定は効果をもたない。設定時、このノードが持ちうるあらゆる可能な子は削除され、その新しい文字列が空やnullでなければ、この属性に設定される文字列を内包する単独のTextノードに置換される。

取得時は、シリアライズは行われず、返される文字列はいかなるマークアップも含まない。空白類の正規化も行われず、返される文字列は要素内容中の空白類を含まない(Text.isElementContentWhitespaceアトリビュートを参照)。同様に、設定時にパース処理は行われず、入力文字列は純粋にテキストコンテンツとして扱われる


和訳は参考訳。URL(IE限定)原文はW3C公式を参照

はい、来ました。複雑怪奇。

わかりづらいと思われる言葉(管理人が理解できなかった言葉)は翻訳中にリンクを付けましたので、リンク先を参照ください。

文章的には、「返される文字列は要素内容中の空白類を含まない(the returned string does not contain the white spaces in element content)」の解釈が難しいです。

以下は管理人の解釈ですが、ここで使われている「要素内容(element content)」という言葉は、単純な「要素の内容」という意図ではなく、SGML における内容モデルの「要素内容」「混合内容」の「要素内容」(その内容にデータは持てず、子要素のみを持つ内容)だと考えます。(参考:要素内容要素型宣言
例えば、HTMLで言えば UL が「要素内容」です。

ということは、つまり、以下の様なHTMLを記述したときに、id="hoge" を textContent で取得したときに返される文字列内には、<ul>タグと初めの<li>タグの間にある空白、タブ、改行は無視される必要がある、また、同様に、</li></ul>の間の改行も無視される、という仕様だと思われます。
「document.getElementById('hoge').textContent」としたときに返ってくる文字列は「要素の内容でーす」であり、空白、改行を含まない、ということです。
<ul id="hoge">
<li>要素の内容でーす</li>
</ul>



【実験その1】

例えば、以下のようなHTML+スクリプトがあります。
<div id="test"> </div>
<script>
alert(document.getElementById('test').textContent == " " );//...(1)
alert(document.getElementById('test').innerText == " " );//...(2)
</script>


このとき、alertであがってくる結果は、以下のとおりです。人間的感覚からするとtrueが返ってきて欲しいところですが……。
なお、Firefoxには innerText プロパティはありません。

IE8:
(1)false
(2)false

Firefox:
(1)true
(2)false

Chrome:
(1)false
(2)false

Safari:
(1)true
(2)false

Opera:
(1)true
(2)true


他方、以下のHTML+スクリプトの場合。
<div id="test"> </div>
<script>
alert(document.getElementById('test').textContent == "" );//...(1)
alert(document.getElementById('test').innerText == "" );//...(2)
</script>


このとき、alertであがってくる結果は、以下のとおりです。
こちらは、人間的感覚からするとfalseが返ってきて欲しいところです。
IE8:
(1)false
(2)true

Firefox:
(1)false
(2)false

Chrome:
(1)false
(2)true

Safari:
(1)false
(2)true

Opera:
(1)false
(2)false

と、結果、Operaが一番素直です。
また、IE君はMSDNに「タグの間にあるテキストを取得するだけだよ」と言いながら、内部的になんかやっているみたいですね。彼のそういうところは今更ですが。


【実験その2】

以下の様なHTMLを実行し、textContent の中身を確認。
<div id="parent">
<-tab spacex10->
<ul id="child">
<li>Lorem ipsum dolor sit amet,</li>
<li>consectetur adipisicing elit ... </li>
<li>et dolore magna aliqua.</li>
</ul>
</div>
<script type="text/javascript">
console.log(document.getElementById('parent').textContent);
console.log(document.getElementById('child').textContent);
</script>


ul要素の空白、タブ、改行は無視され……無いです。むむっ。
解釈が間違っていたのか……。

しかし、これ以上は調査する気力がなくなりました。


【結論】

素直にjQueryなどのライブラリを使ってしまったほうがいいと思いました。
$.trim(text()).length で真偽判定する、等々。


【関連項目】

DOM の textContent と innerText について
「フリーフォーム フリークアウト」さん。同じ内容についてまとめられています。
「まず要件をもう一度みなおして本当に textContent / innerText が必要か考える. 大抵の場合は innerHTML からタグを取り除くだけで十分.」には私も賛成です。

Plain Text vs innerText vs textContent
クロスブラウザの "getPlainText()" という関数が紹介されています。
このサイトで「the returned string does not contain the white spaces in element content.」が解決できると思ったら、触れられずスルーされてました。。。英語ネイティブの人にはややこしく無いのかなぁ。