MENU

JavaScriptDOM関数・メソッド

【JavaScript】 2020年版innerHTML/innerText/textContentの違い

更新日:2020/07/27

 

 

僕は今までDOM要素に文字列をセットするときinnerTextを使っていましたが、最近textContentも同じことができると知りました。
そこで詳しくネットで調べてみるとかなり古い情報が多く、現在の状況とマッチしていないようです。

 

そこで今回は、innerTextとtextContentおよびinnerHTMLにおいて、今現在(2020/6)はどのような違いがあるのかをお伝えします。

 

 

検証結果のまとめ

 

まずは検証した結果からお伝えします。

 

表の値の取得は、Div要素からinnerHTML/innerText/textContentを使用して取得した値の特徴について解説しています。

 

値のセットは、タグを含んだ文字列をDiv要素のinnerHTML/innerText/textContentにセットしたときにどうなるかを解説しています。

 

プロパティ 値の取得 値のセット
innerHTML
  • タグを返す
  • htmlのソースイメージの通りに

    スペースや改行が挿入される。

  • タグが解析され

    DOM要素が構築される。

  • 改行コード・スペースは

    内部的に保持される。

innerText
  • タグを返さない。
  • white-space属性の影響を受け

    表示イメージの通りに
    スペースや改行コード
    が挿入される。

  • タグは解析されず、

    文字列として登録される。

  • 改行コードは、

    <br>要素として登録される。

  • カッコ(<>)と&が

    エンティティ(&lt;、&gt;、&amp;)
    に変換される。

  • スペースは

    内部的に保持される。

textContent
  • タグを返さない。
  • htmlのソースイメージの通りに

    スペースや改行コード
    が挿入される。

  • タグは解析されず、

    文字列として登録される。

  • カッコ(<>)と&が

    エンティティ(&lt;、&gt;、&amp;)
    に変換される。

  • 改行コード・スペースは

    内部的に保持される。

 

innerTextは少し特殊で、取得時にスタイル属性white-spaceの影響を受けます。
他の二つは影響をうけません。

 

ちなみにこれらのプロパティは、イコールを使用して値の取得・セットをおこないます。

 

例:
dom要素.innerHTML = 変数(文字列)
変数 = dom要素.innerHTML

 

イコールは代入操作ですが、直接プロパティに代入されるわけではなく、内部的に解析処理がおこなわれます。
例えば、innerHTMLは文字列を解析してDOMを構築します。

 

詳しくは、次の記事を見てください。
参考記事:【JavaScript】 ゲッター・セッターとは?必要性はあるのか?

検証1:データを取得する

 

まずはDOM要素として構築されているデータを取得したとき、各プロパティの違いについて検証してみます。

 

テストデモ

 

次のデモは、表示イメージとして用意したDOM要素をinnerHTML・innerText・textContentで取得して内容を表示しています。

 

ただし表示の際に、スペースを緑の下線(_)で表示しています。
また改行コードを青文字(\n)で表示しています。

 

改行コードやスペース・HTMLエンティティの取り扱いを確認したいので、htmlコードにそれぞれの要素を含ませています。

 

white-spaceは、スタイル属性のwhite-spaceを設定します。
white-space属性は、改行やスペースの画面表示方法に関する属性です。
このセレクトボックスを変更すると、innerHTML・innerText・textContentを再取得します。

 

テストデモ

 

<div>\n スペース____←4個<br>\n <span_style="color:red">red\n color</span><br>\n <span_style="color:blue">青い\n 文字</span><br>\n &lt;span&nbsp;style=&quot;color:green&quot;&gt;緑\n 文字&lt;/span&gt;\n </div>\n
スペース ←4個
red color
青い 文字
<span style="color:green">緑 文字</span>

innerHTMLの取得結果

innerTextの取得結果

textContentの取得結果

ブラウザのユーザーエージェント

 

innerHTML

 

上の結果を見ると、innerHTMLはタグを含んだ文字列を返しています。
また改行やスペース・HTMLエンティティは、元のhtmlソースのイメージそのままで取得しています。

 

white-space属性を変更しても、取得結果は変わりません。

 

innerText

 

innerTextはタグが削除されます。
またHTMLエンティティは、対応する文字に変換されます。

 

innerTextはwhite-space属性の影響を受けます
表示されているイメージの通りに改行とスペースがセットされます。

 

textContent

 

textContentはタグが削除されます。
またHTMLエンティティは、対応する文字に変換されます。

 

textContentはwhite-space属性の影響を受けません
改行およびスペースは、元のhtmlソースのイメージそのままで取得しています。

 

innerText捕捉

 

white-space属性で改行コードで改行を行わないキーワード(normal等)を指定した場合、改行コードはスペースに変更されます。
しかしブラウザによって、動作が異なることがあります。

 

次の図は、Google Chrome84.0.4147.89でのキャプチャ画像です。
redとcolorの間。
青いと文字の間にスペースが挿入されています。

 

white-space属性 chrome

 

innerTextの値にもスペースが挿入されています。

 

スペース_←4個\nred_color\n青い_文字\n<span_style="color:green">緑_文字</span>

 

次の図は、Firefox78.0.2でのキャプチャ画像です。
redとcolorの間にスペースが挿入されています。
しかし青いと文字の間にスペースが挿入されていません。

 

クライアント

 

innerTextの値にも青い文字の間にスペースが挿入されていません。

 

スペース_←4個\nred_color\n青い文字\n<span_style="color:green">緑_文字</span>

 

どうやら日本語文字でのスペースの取り扱い方法が異なるようです。

検証2:文字列をセットしたときの動作

 

次は文字列をDOM要素にセットしたときの違いについて検証してみます。

 

テストデモ

 

下のテストデモはテキストボックスに入力した文字列を、innerHTML、innerText、textContentを使用してdiv要素にセットしています。
ただし文字列中の"\n"については、セット前に改行コードに変換しています。

 

また、div要素はwhite-space属性にnormal(改行をスペースに変換)を指定したものと、pre(改行をそのまま反映)を指定したものの2種類用意してあります。

 

div要素セット後にdiv要素のinnerHTMLを取得して、表示しています。
これにより、データ文字列をどのようにDOM要素に展開しているか確認できます。

 

 

テキストボックスには初期値としてタグとHTMLエンティティ入りの文字列が入力されています。
そのまま反映ボタンを押してみてください

 

テストデモ

 

データ文字列

データ文字列を innerHTML にセット

innerHTMLで取得

データ文字列を innerText にセット

innerHTMLで取得

データ文字列を textContent にセット

innerHTMLで取得

ブラウザのユーザーエージェント

 

innerHTMLの結果

 

innerHTMLはタグが解析され、DOM要素が構築されます。

 

また改行・スペース・HTMLエンティティは、そのまま文字列として取り込まれます。

 

 

innerTextの結果

 

innerTextはデータを文字列として取り込みます。
その際、カッコ(<>)と&がエンティティ(&lt;、&gt;、&amp;)に変換されます。

 

スペースはそのまま取り込まれます。

 

改行コードは<br>タグに変換され、DOM要素として登録されます。
これによりwhite-space属性に関係なく、画面表示時に改行されます。

 

textContent の結果

 

textContentはデータを文字列として取り込みます。
その際、カッコ(<>)と&がエンティティ(&lt;、&gt;、&amp;)に変換されます。

 

スペース・改行コードはそのまま取り込まれます。
white-space属性が改行コードで改行させないキーワードの場合、改行されません。

参考:ソースコード

 

参考になる部分はあまりないと思いますが、検証で使用したプログラムのソースコードを紹介します。

 

CSS

 

共通スタイル

 


.tarea,.tarea2{
    width:95%;
    height:100px;
    padding:10px;
    background:white;
}
.tarea2{
    white-space:pre;
    overflow:auto;
}
.tdivarea{
    width:95%;
    margin:0 0 1em 0;
    border: 1px solid black;
    padding:2em 10px 10px 10px;
    background:white;
    position: relative;
    overflow: auto;
    display: block;
}
.tdivarea.divarea{
    white-space: nowrap;
}
.tdivarea:before{
    position: absolute;
    top: 0;
    width: 100%;
    background: gray;
    left: 0;
    color: white;
}
.tbutton{
    width:98%;
    margin: 5px auto 1em;
}
.flx{
    display: flex;
    width: 95%;
}
.divarea{ white-space:normal; }

.divarea:before{
    content: "【white-space:normal】";
}
.prearea{ white-space:pre; }
.prearea:before{
    content: "【white-space:pre】";
}
#htmlarea{white-space:pre;
}
#htmlarea:before{
    content: "【HTML】";
}
#htmlviewarea:before{
    content: "【表示イメージ】";
}
.rtcolor{color:blue;margin: 0 2px;}
.spcolor{color:green;margin: 0 2px;}
.waku p:first-child{
    position: absolute;
    top:-1em;
    font-weight: bold;
    background: white;
    padding: 0 1em;
}
.waku{
    border: 1px solid black;
    padding: 1.5em 10px;
    position: relative;
    margin:1em 0 2em 0;
}
.ws-normal{white-space:normal;}
.ws-nowrap{white-space:nowrap;}
.ws-pre{white-space:pre;}
.ws-pre-wrap{white-space:pre-wrap}
.ws-pre-line{white-space:pre-line;}

 

検証1

 

HTML

 


<label>white-space:
<select name="ws1" id="whiteSpBox">
<option value="ws-normal" selected>normal</option>
<option value="ws-nowrap">nowrap</option>
<option value="ws-pre">pre</option>
<option value="ws-pre-wrap">pre-wrap</option>
<option value="ws-pre-line">pre-line</option>
</select></label>

<div class="flx">
<div id="htmlarea" class="tdivarea">&lt;div&gt;<span class="rtcolor">\n</span>
スペース<span class="spcolor">_</span><span class="spcolor">_</span><span class="spcolor">_</span><span class="spcolor">_</span>←4個&lt;br&gt;<span class="rtcolor">\n</span>
&lt;span<span class="spcolor">_</span>style=&quot;color:red&quot;&gt;red<span class="rtcolor">\n</span>
color&lt;/span&gt;&lt;br&gt;<span class="rtcolor">\n</span>
&lt;span<span class="spcolor">_</span>style=&quot;color:blue&quot;&gt;青い<span class="rtcolor">\n</span>
文字&lt;/span&gt;&lt;br&gt;<span class="rtcolor">\n</span>
&amp;lt;span&amp;nbsp;style=&amp;quot;color:green&amp;quot;&amp;gt;緑<span class="rtcolor">\n</span>
文字&amp;lt;/span&amp;gt;<span class="rtcolor">\n</span>
&lt;/div&gt;<span class="rtcolor">\n</span></div>
<div id="htmlviewarea" class="tdivarea">
<div>
スペース    ←4個<br>
<span style="color:red">red
color</span><br>
<span style="color:blue">青い
文字</span><br>
&lt;span style=&quot;color:green&quot;&gt;緑
文字&lt;/span&gt;
</div>
</div>
</div>

<div class="waku"><p>innerHTMLの取得結果</p>
<div id="innerHTMLGetArea" class="tarea2"></div>
</div>

<div class="waku"><p>innerTextの取得結果</p>
<div id="innerTextGetArea" class="tarea2"></div>
</div>
<div class="waku"><p>textContentの取得結果</p>
<div id="textContentGetArea" class="tarea2" ></div>
</div>
<p id="black">ブラウザのユーザーエージェント</p>
<p id="yourbrowser1"></p>

 

 

JavaScript

 


window.addEventListener( "DOMContentLoaded" , ()=> {
    const replaceHtml = t =>
        t.replace(/["<>\n &]/g,
            e=> ({  '"':"&quot;",
                "&" : "&amp;",
                "<":"&lt;",
                ">":"&gt;",
                "\n":'<span class="rtcolor">\\n</span>' ,
                " " :'<span class="spcolor">_</span>'})[e]
        ).replace( /&lt;br&gt;/g , '<span class="rtcolor">&lt;br&gt;</span>');

    const setWhiteSpace = (e,selbox) =>{
        [   "ws-normal",
            "ws-nowrap",
            "ws-pre",
            "ws-pre-wrap",
            "ws-pre-line",
            "ws-break-spaces"].forEach( s => e.classList.remove(s));
        e.classList.add( selbox.value );
    };

    document.getElementById("yourbrowser1").innerText =  window.navigator.userAgent;

    const htmlviewarea = document.getElementById("htmlviewarea");
    const whiteSpBox = document.getElementById("whiteSpBox");
    const innerHTMLGetArea = document.getElementById("innerHTMLGetArea");
    const innerTextGetArea = document.getElementById("innerTextGetArea");
    const textContentGetArea = document.getElementById("textContentGetArea");

    const setData = ()=>{
        innerHTMLGetArea.innerHTML = replaceHtml(htmlviewarea.innerHTML);
        innerTextGetArea.innerHTML = replaceHtml(htmlviewarea.innerText);
        textContentGetArea.innerHTML = replaceHtml(htmlviewarea.textContent);
    };
    setWhiteSpace( htmlviewarea , whiteSpBox);
    setData();
    whiteSpBox.addEventListener( "change" , ()=> {
        setWhiteSpace( htmlviewarea , whiteSpBox);
        setData();
    });

});

 

 

検証2

 

 

HTML

 


<p class="black">データ文字列</p>
<textarea id="dataArea" class="tarea">スペース    ←4個<br>\n<span style="color:red">red\ncolor</span><br>\n<span style="color:blue">青い\n文字</span><br>\n&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;緑の\n文字&amp;lt;/span&amp;gt;</textarea>
<button id="setbutton" class="tbutton">反映</button>
<div class="waku"><p>データ文字列を innerHTML にセット</p>
<div class="flx">
<div id="innerHTMLSetDivArea" class="tdivarea divarea"></div>
<div id="innerHTMLSetPreArea" class="tdivarea prearea"></div>
</div>
<p class="black">innerHTMLで取得</p>
<div id="innerHTMLCheckArea" class="tarea2" ></div>
</div>
<div class="waku"><p>データ文字列を innerText にセット</p>
<div class="flx">
<div id="innerTextSetDivArea"  class="tdivarea divarea"></div>
<div id="innerTextSetPreArea"  class="tdivarea prearea"></div>
</div>
<p class="black">innerHTMLで取得</p>
<div id="innerTextCheckArea" class="tarea2" ></div>
</div>
<div class="waku"><p>データ文字列を textContent  にセット</p>
<div class="flx">
<div id="textContentSetDivArea"  class="tdivarea divarea"></div>
<div id="textContentSetPreArea"  class="tdivarea prearea"></div>
</div>
<p class="black">innerHTMLで取得</p>
<div id="textContentCheckArea" class="tarea2" ></div>
</div>
<p id="black">ブラウザのユーザーエージェント</p>
<p id="yourbrowser2"></p>

 

 

JavaScript

 

window.addEventListener( "DOMContentLoaded" , ()=> {

    const replaceHtml = t =>
        t.replace(/["<>\n &]/g,
            e=> ({  '"':"&quot;",
                "&" : "&amp;",
                "<":"&lt;",
                ">":"&gt;",
                "\n":'<span class="rtcolor">\\n</span>' ,
                " " :'<span class="spcolor">_</span>'})[e]
        ).replace( /&lt;br&gt;/g , '<span class="rtcolor">&lt;br&gt;</span>');

    document.getElementById("yourbrowser2").innerText =  window.navigator.userAgent;

    document.getElementById("setbutton").addEventListener("click",()=>{
        const testData = document.getElementById("dataArea").value.replace(/\\n/g,"\n");

        document.getElementById("innerHTMLSetDivArea").innerHTML = testData;
        document.getElementById("innerHTMLSetPreArea").innerHTML = testData;
        document.getElementById("innerHTMLCheckArea").innerHTML = replaceHtml(document.getElementById("innerHTMLSetDivArea").innerHTML);

        document.getElementById("innerTextSetDivArea").innerText = testData;
        document.getElementById("innerTextSetPreArea").innerText = testData;
        document.getElementById("innerTextCheckArea").innerHTML = replaceHtml(document.getElementById("innerTextSetDivArea").innerHTML);

        document.getElementById("textContentSetDivArea").textContent = testData;
        document.getElementById("textContentSetPreArea").textContent = testData;
        document.getElementById("textContentCheckArea").innerHTML = replaceHtml(document.getElementById("textContentSetDivArea").innerHTML);
    });
});

記事の内容について

 

こんにちはけーちゃんです。
説明するのって難しいですね。


「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。

そんなときは、ご意見もらえたら嬉しいです。

ご意見はこちら。
https://affi-sapo-sv.com/info.php