「innerText」はIEでは機能しますが、Firefoxでは機能しません


289

IEで動作する次のJavaScriptコードが含まれています。

myElement.innerText = "foo";

ただし、Firefoxでは「innerText」プロパティが機能しないようです。Firefoxに相当するものはありますか?または、使用できるより一般的なクロスブラウザープロパティはありますか?


3
これはmyElement.innerHTML = "foo";
stefita 2009

これにより、オブジェクト内のすべてのHTMLが指定された値に置き換えられます。
OMGポニー

24
これは、jQueryのようなライブラリーが、標準のフレームワークを使用できるようにすることで、このようなブラウザー間の不整合を処理するので、作業を容易にする場所です。
ダン・ディプロ

ただし、処理するHTMLがない場合は、依然として適している可能性があります。
Alex Polo

21
だから、それが可能であると言っているだけではなく、このクロスブラウザの代替の使用方法を教えてください(これは建設的ではありません)。
SasQ 2012

回答:


249

FirefoxはW3C準拠の textContentプロパティを使用します。

SafariとOperaもこのプロパティをサポートしていると思います。



2
@ボブ2016年2月22日現在、まだそうではありません。
クリルガー、2016

@krillgar 3月8日の週にリリースされる予定のFirefox 45で予定されています。それは現在のベータリリースに既にあり、しばらくの間オーロラにありました。これが実際に意味することは、innerTextonlyを使用してサイトの開発を開始し、近い将来に現在のすべてのブラウザーで、そして古いIEでも(奇妙な動作で)動作することを期待できるということです。
ボブ

1
FTR:innerTextある深く違うからtextContent(...意外に推定IEの癖から)、および実際には非常に便利です:innerTextテキストがされる方法の近似与えることをしようと、実際に提示全く異なり、ブラウザでのtextContentちょうど約返す、タグ-マークアップソースの除去、ほとんど付加価値のない問題、または余分な問題(単語の境界の喪失など)。
Sz。

innerTextはまだバージョン64に2019年にサポートしていない
トニードン

285

更新すべての違いを詳しく説明しブログ投稿を書きました。


FirefoxはW3C標準を使用しますNode::textContentが、その動作はMSHTMLの独自仕様とは「わずかに」異なりますinnerText(Operaによってコピーされたもので、以前は他の多数のMSHTML機能の一部ます。

まず、textContent空白の表現はinnerText1つとは異なります。2つ目は、さらに重要なことに、textContent すべてのSCRIPTタグの内容を含みます、innerTextには含まれていません。

標準実装のほかに-ちょうど、オペラを楽しまより多くのものを作るためにtextContent-もMSHTMLのを追加することにしましたinnerText が、それはとして機能するように変更textContent -つまり、スクリプトの内容(実際には含めて、textContentinnerTextオペラ座では、同じ結果を生成するように見えるおそらくちょうどお互いにエイリアスされています) 。

textContentNodeインターフェースの一部ですが、innerTextはの一部ですHTMLElement。たとえば、これはテキストノードからでtextContentはなく「取得」できることを意味しますinnerText

var el = document.createElement('p');
var textNode = document.createTextNode('x');

el.textContent; // ""
el.innerText; // ""

textNode.textContent; // "x"
textNode.innerText; // undefined

最後に、Safari 2.xにもバグのあるinnerText実装があります。SafariではinnerText、要素が(を介してstyle.display == "none")非表示にされていないか、ドキュメントから孤立していない場合にのみ、正しく機能します。それ以外の場合innerTextは、空の文字列になります。

私はtextContent(これらの欠陥を回避するために)抽象化を試していましたが、かなり複雑であることがわかりました

最善の策は、最初に正確な要件定義し、そこから従うことです。単にのオフタグを除去することが可能である場合が多いinnerHTMLという可能性のすべてとの契約よりも、要素のtextContent/innerText偏差です。

もちろん、もう1つの可能性は、DOMツリーをウォークしてテキストノードを再帰的に収集することです。


35
ChromeはinnerTextもサポートしているため、Firefoxがそれをサポートしない唯一の主要なブラウザーのようです。そして、IEはtextContentをサポートしない唯一のブラウザです。
マイクネルソン、2010

7
@mike-しかしinnerText、Chromeでの使用は60倍遅くなるようです。jsperf.com/text-content/3
gblazex

8
textContentは現在IE9 +でサポートされていますが、FirefoxはまだサポートしていませんinnerText(ただし、outerHTMLほんの数日前に導入されたIEを追加しました)。
kangax 2011年

1
まだIE8をサポートする必要がある人のために、github.comNode.textContent / usmonster / aight / blob / node-textcontent- shim / js / (うまくいけばすぐにaightに含まれる)で、かなり完全なシムが進行中です。
Noyo


83

テキストコンテンツを設定するだけで取得する必要がない場合は、どのブラウザーでも使用できる簡単なDOMバージョンを以下に示します。IE innerText拡張機能またはDOM Level 3 Core textContentプロパティは必要ありません。

function setTextContent(element, text) {
    while (element.firstChild!==null)
        element.removeChild(element.firstChild); // remove all existing content
    element.appendChild(document.createTextNode(text));
}

JavaScriptに「!==」演算子がない限り、2行目の演算子は「!=」だけでよいと思います。
RexE、2011年

23
@RexE:JavaScriptには!==、の逆の演算子があり===ます。===/ によって使用される型依存の比較!==は、通常、ルーズコンパレーター==/に優先し!=ます。
ボビンス、2011年

Internet Explorerでは、これはスクリプトタグのテキストを設定するために機能しません(私はテンプレートに使用していました)。`scriptTagElement.text = 'my template {{here}}';を設定しました。
Christopher Tarquini

ループを単に置き換えるのではなく、なぜループを使用したのか(そして、完全に破棄します)を理解するのは非常に難しいと思い!==nullましたelement.innerHTML=''(ループとまったく同じ作業を行うことが指定されているので、覚えていました)。 。:(legacy-)IEの表... ericvasilik.com/2006/07/code-karma.html 「隠された」という短い説明を追加することをお勧めしますが、amp lt を置き換えることによる「副作用」はほとんど文書化されていませんcreateTextNodeおよびgtをそれぞれのhtml文字エンティティに?正確な動作へのリンクは壮大です!
GitaarLAB


22

Prakash Kの回答に従って、FirefoxはinnerTextプロパティをサポートしていません。したがって、ユーザーエージェントがこのプロパティをサポートしているかどうかをテストし、それに応じて以下のように続行できます。

function changeText(elem, changeVal) {
    if (typeof elem.textContent !== "undefined") {
        elem.textContent = changeVal;
    } else {
        elem.innerText = changeVal;
    }
}

2
elemの 'textContent'の方が簡単です
Jamie Pate

if(elem.textContent!= null)も簡単です!
Elmue 2016年

14

Javascriptの非常に単純な行は、すべてのメインブラウザーで「くすんだ」テキストを取得できます...

var myElement = document.getElementById('anyElementId');
var myText = (myElement.innerText || myElement.textContent);

2
これには問題があります(少なくともIE8では):innerTextが空の文字列であり、textContentが未定義の場合、(myElement.innerText || myElement.textContent)は未定義になります。
Magnus

1
@Magnusによって指摘されたバグだけでなく、一部のユースケースで問題になる可能性のある空白レポートの方法textContentinnerTextには大きな違いがあることにも注意する必要があります。
Mark Amery

2
||つまり、別のを追加するだけvar myText = (myElement.innerText || myElement.textContent || "") ;です。つまり、未定義の値を克服します。
PeterM 2015

6

このElement::innerTextプロパティには、Google ChromeのCSSスタイル " " によって非表示にされたテキストが含まれないことに注意してくださいdisplay:none(また、他のCSSテクニック(font-size:0、color:transparentなどを含む)によってマスクされたコンテンツがドロップされますテキストが表示されないようにする他のいくつかの同様の効果)。

その他のCSSプロパティも考慮されます。

  • 最初に、内部要素の「display:」スタイルが解析され、それがブロックのコンテンツを区切るかどうかが決定されます(ブラウザの組み込みスタイルシートのHTMLブロック要素のデフォルトである「display:block」など)。独自のCSSスタイル); その場合、innerTextプロパティの値に改行が挿入されます。これは、textContentプロパティでは発生しません。
  • インラインコンテンツを生成するCSSプロパティも考慮されます。たとえば、<br \>インライン改行を生成するインライン要素は、innerTextの値に改行も生成します。
  • "display:inline"スタイルでは、textContentとinnerTextのどちらにも改行はありません。
  • "display:table"スタイルはテーブルの周りとテーブル行の間に改行を生成しますが、 "display:table-cell"は集計文字を生成します。
  • 「position:absolute」プロパティ(display:blockまたはdisplay:inlineで使用されます。重要ではありません)でも、改行が挿入されます。
  • 一部のブラウザには、スパン間の単一のスペース分離も含まれます

ただしElement::textContent、非表示であっても、適用されたCSSに関係なく、内部テキスト要素のすべてのコンテンツが含まれます。また、textContentに余分な改行や空白は生成されません。これは、すべてのスタイルと構造、および内部要素のインライン/ブロックまたは配置タイプを無視するだけです。

マウス選択を使用したコピー/貼り付け操作は、クリップボードに保存されているプレーンテキスト形式の非表示テキストを破棄するため、 textContentinnerText(上記のように空白/改行が生成された後)内にあるもののみが。

その後、両方のプロパティがGoogle Chromeでサポートされますが、それらのコンテンツは異なる場合があります。古いブラウザは、textContentに現在含まれているものと同様に、すべてinnetTextに含まれていました(ただし、空白/改行の生成に関連する動作は一貫していませんでした)。

jQueryは、$()クエリを介して返される解析済み要素に追加された「.text()」メソッドを使用して、ブラウザー間のこれらの不整合を解決します。内部的には、「ノード」レベルでのみ機能し、HTML DOMを調べることで問題を解決します。したがって、標準のtextContentに似たものを返します。

注意点は、このjQueryメソッドは、サブ要素(以下のような)が原因で画面に表示される可能性がある余分なスペースや改行を挿入しないことです。 <br />、コンテンツの)がです。

アクセシビリティ用のスクリプトをいくつか設計し、点字リーダーとの通信に使用するプラグインなど、非オーラルレンダリング用にスタイルシートを解析する場合、このツールは、スタイルが設定されたスパンに追加される特定の句読記号を含める必要がある場合、textContentを使用する必要があります。 "display:none"であり、通常はページに含まれます(たとえば、上付き文字/下付き文字)。それ以外の場合、innerTextは点字リーダーで非常に混乱します。

HTML / CSSパーサーとDOMプロパティを使用して、CSSトリックによって非表示にされたテキストは、通常、主要な検索エンジンによって無視されます(HTMLページのCSSも解析され、背景の対比色でないテキストも無視されます)。 "innerText"は、最新のビジュアルブラウザーとまったく同じです(少なくともこの非表示のコンテンツはインデックスに登録されないため、ページにキーワードを含めてコンテンツをチェックさせるためのトリックとして非表示のテキストを使用することはできません)。ただし、この非表示のテキストは結果ページに表示され(ページがインデックスに含まれるように修飾されている場合)、完全なHTMLの代わりに「textContent」プロパティを使用して、余分なスタイルとスクリプトを取り除きます。

これら2つのプロパティのいずれかにプレーンテキストを割り当てると、内部のマークアップとそれに適用されたスタイルが上書きされ(割り当てられた要素のみがそのタイプ、属性、スタイルを保持します)、両方のプロパティに同じコンテンツが含まれます。 。ただし、一部のブラウザーはinnerTextへの書き込みを受け付けなくなり、textContentプロパティの上書きのみを許可します(これらのプロパティへの書き込み時にHTMLマークアップを挿入することはできません。HTML特殊文字は、文字参照を使用して正しくエンコードされ、文字どおりに表示されるためです。 、またはinnerHTMLの割り当て後にプロパティを読み取ったinnerText場合textContent


1
実際には、「font-size:0」、「color:transparent」、「opacity:0」、「text-indent:-9999px」などがすべてChrome / WebKitに含まれていinnerTextます。私のテストでは、「display:none」と「visibility:hidden」のみが無視されます。
kangax

5
myElement.innerText = myElement.textContent = "foo";

編集(以下のコメントについてMark Ameryに感謝):このような方法で行うのは、たとえば、次のように、これらのプロパティの存在の確認に依存するコードがないことが合理的な疑いを超えてわかっている場合のみです。 jQueryの。しかし、jQueryを使用している場合、他のいくつかの回答が示すように、おそらく「テキスト」関数を使用して$( '#myElement')。text( 'foo')を実行します。


4
-1; これは悪い考えです。jQueryなどのライブラリのコードを含むコードでは、innerTextまたはの存在を確認して、どちらtextContentを使用するかを決定することは非常に一般的です。両方を文字列に設定すると、要素に作用する他の人のコードが、ブラウザーが両方のプロパティをサポートしていることを誤って検出してしまいます。その結果、そのコードは誤動作しやすくなります。
Mark Amery

JQuery $( '#myElement')。val()はクロスブラウザーで動作します。
トニー・ドン

4

innerText Firefoxに追加され、FF45リリースで利用可能になるはずです。 https

ドラフト仕様が書かれており、将来的にはHTMLの生活水準に組み込まれることが予想される:http://rocallahan.github.io/innerText-spec/https://github.com/whatwg/html/issues/ 465

現在、Firefox、Chrome、IEの実装はすべて互換性がないことに注意してください。今後は、Firefox、Chrome、およびEdgeが統合され、古いIEは互換性がないままになることが予想されます。

参照:https : //github.com/whatwg/compat/issues/5


ポリフィルはありますか?
serv-inc

1
@user本当に必要なものに依存します。古いバージョンのFirefoxをサポートする必要がなく、実装の小さな違いを気にしない場合は、を使用してくださいinnerTexttextContentが許容できるフォールバックであり、古いFxをサポートする必要がある場合は、を使用します(innerText || textContent)。すべてのブラウザーで同一の実装が必要な場合、これに特定のポリフィルがあるとは思われませんが、一部のフレームワーク(jQueryなど)はすでに同様のものを実装している可能性があります。このページの他の回答を参照してください。
ボブは

1
の機能innerText、つまり、Firefoxのページに表示されるテキスト> = 38(アドオンの場合)少なくとも、<script>タグは完全に省略する必要があります。jQuery $('#body').text()は私にとってはうまくいきませんでした。しかし、回避策としてinnerText || textContentは問題ありません。ありがとうございました。
serv-inc

@userはい、Fx 38をサポートする必要がある場合、この答えは実際には当てはまりません。あなたはtextContent今のところの制限/違いに耐えなければなりません。
ボブ

1

このようなものはどうですか?

//$elem is the jQuery object passed along.

var $currentText = $elem.context.firstChild.data.toUpperCase();

**私は大文字にする必要がありました。


1
クラップ液; 要素に1つ以上のテキストノードが含まれている場合、これは機能しません。
Mark Amery


0

これは私の経験されているinnerTexttextContentinnerHTML、および値:

// elem.innerText = changeVal;  // works on ie but not on ff or ch
// elem.setAttribute("innerText", changeVal); // works on ie but not ff or ch
// elem.textContent = changeVal;  // works on ie but not ff or ch
// elem.setAttribute("textContent", changeVal);  // does not work on ie ff or ch
// elem.innerHTML = changeVal;  // ie causes error - doesn't work in ff or ch
// elem.setAttribute("innerHTML", changeVal); //ie causes error doesn't work in ff or ch
   elem.value = changeVal; // works in ie and ff -- see note 2 on ch
// elem.setAttribute("value", changeVal); // ie works; see note 1 on ff and note 2 on ch

ie = Internet Explorer、ff = firefox、ch = google chrome。注1:ffは、値がバックスペースで削除されるまで機能します-上記のレイベガによるメモを参照してください。注2:Chromeで多少動作します-更新後も変更されないため、クリックしてフィールドに戻り、値が表示されます。ロットの最高はelem.value = changeVal; 上記ではコメントアウトしていません。


1
私だけでしょうか ?または、絶対にOP質問を無視しますか?彼はinnerText / textContentを求め、あなたは主に入力について話している。
認知症の

この答えは非常に読みにくいです。一方、コンテンツが整理するに値する十分な価値があるとは思いません。
Mark Amery

-1

元の投稿の下にあるコメントから再投稿するだけです。innerHTMLはすべてのブラウザで機能します。stefitaに感謝します。

myElement.innerHTML = "foo";


1
-1; /のinnerHTML適切な置き換えではありません。ただし、割り当てているテキストにタグや他のHTML構文が含まれていないことが確実な場合は除きます。ユーザーが提供するデータについては、その保証はありません。XSSのセキュリティホールにつながる可能性があるため、この警告なしにこのアプローチを実行することは危険です。非常に多くの安全なアプローチが利用できるので、これを検討する理由すらありません。textContentinnerText
Mark Amery

マーク、私の理解では、innerHTMLはdiv、span、pなどのhtml要素にデータを書き込む通常の方法です。返されたJSONデータを処理するために使用します。それもJQueryにあります...
Leonid Alzhin

1
JSON応答から任意の文字列を取得し、それを要素のに割り当てると.innerHTML、コードが破損し、XSSに対して脆弱になる可能性があります。その文字列がある場合は"<script>alert(1)</script>"どうなりますか?
Mark Amery、2015

1
@MarkAmery:HTML5では、<script>経由innerHTMLで挿入されたタグを実行しないように指定しています。しかし、それは古いブラウザを保護するものではありません。また、HTML5 innerHTMLは、たとえば保護しません"<img src='x' onerror='alert(1)'>"
GitaarLAB 2017年

-1

これをここに見つけました:

<!--[if lte IE 8]>
    <script type="text/javascript">
        if (Object.defineProperty && Object.getOwnPropertyDescriptor &&
            !Object.getOwnPropertyDescriptor(Element.prototype, "textContent").get)
          (function() {
            var innerText = Object.getOwnPropertyDescriptor(Element.prototype, "innerText");
            Object.defineProperty(Element.prototype, "textContent",
              { // It won't work if you just drop in innerText.get
                // and innerText.set or the whole descriptor.
                get : function() {
                  return innerText.get.call(this)
                },
                set : function(x) {
                  return innerText.set.call(this, x)
                }
              }
            );
          })();
    </script>
<![endif]-->

いくつかの説明がいいでしょう!また、ここには奇妙なたわごとがあります。なぜときIE> = 9、というだけでIE 8をターゲットにするよりも、IE> = 8に実行を制限するために、条件付きコメントを使用してサポートtextContentをネイティブ?また、動作が異なるためinnerTexttextContent上記のコードは忠実なtextContentシムではありません。これは重要である可能性がありますが、必ずしも明白ではありません。
Mark Amery

欠陥を指摘してくれてありがとう、それはIE <= 8
simonarame

-2

innerText他のブラウザで動作をエミュレートすることも可能です:

 if (((typeof window.HTMLElement) !== "undefined") && ((typeof HTMLElement.prototype.__defineGetter__) !== "undefined")) {
     HTMLElement.prototype.__defineGetter__("innerText", function () {
         if (this.textContent) {
             return this.textContent;
         } else {
             var r = this.ownerDocument.createRange();
             r.selectNodeContents(this);
             return r.toString();
         }
     });
     HTMLElement.prototype.__defineSetter__("innerText", function (str) {
         if (this.textContent) {
             this.textContent = str;
         } else {
             this.innerHTML = str.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/\n/g, "<br />\n");
         }
     });
 }

私の頭の上の問題を探しているだけで、セッターはpre改行を2倍にするのでsの間壊れています。ここにはもっと問題があると思います。
Mark Amery
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.