Perbedaan antara textContent vs innerText

157

Apa perbedaan antara textContent dan innerTextdalam JavaScript?

Dapatkah saya menggunakan textContentsebagai berikut:

var logo$ = document.getElementsByClassName('logo')[0];
logo$.textContent = "Example";
JK
sumber
3
Mereka sama, tetapi beberapa browser mendukung satu sama lain.
Runcing
@Pointy apa yang didukung semua browser?
Yehia Awad
6
Sebuah posting yang baik blog tentang itu
Tyblitz
4
@Pointy silakan merujuk ke posting blog yang saya tunjuk. Pernyataan Anda salah, ada perbedaan.
Tyblitz
3
innerTextdan textContentjelas tidak sama. Peristiwa white-space dalam konten node akan menyebabkan dua properti menghasilkan konten yang berbeda, dan demikian juga akan terjadi brelemen dan keturunan yang dihasilkan tingkat blok lainnya.
amn

Jawaban:

211

Tidak ada jawaban lain yang berhasil memberikan penjelasan lengkap, karenanya yang ini. Perbedaan utama antara innerTextdan textContentdiuraikan dengan sangat baik di posting blog Kelly Norton: innerText vs textContent . Di bawah ini Anda dapat menemukan ringkasan:

  1. innerTexttidak standar, sedangkan textContentstandar sebelumnya.
  2. innerTextmengembalikan teks yang terlihat yang terkandung dalam sebuah node, sementara textContentmengembalikan penuh teks . Misalnya, pada HTML berikut <span>Hello <span style="display: none;">World</span></span>, innerTextakan mengembalikan 'Hello', sementara textContentakan mengembalikan 'Hello World'. Untuk daftar perbedaan yang lebih lengkap, lihat tabel di http://perfectionkills.com/the-poor-misunderstood-innerText/ (bacaan lebih lanjut di 'innerText' berfungsi di IE, tetapi tidak di Firefox ).
  3. Akibatnya, innerTextjauh lebih berat karena membutuhkan informasi tata letak untuk mengembalikan hasilnya.
  4. innerText didefinisikan hanya untuk HTMLElement objek, sedangkan textContentdidefinisikan untuk semua Nodeobjek.

Solusi untuk textContentdi IE8- akan melibatkan fungsi rekursif menggunakan nodeValuepada semua childNodesnode yang ditentukan, berikut ini coba di polyfill:

function textContent(rootNode) {
  if ('textContent' in document.createTextNode(''))
    return rootNode.textContent;

  var childNodes = rootNode.childNodes,
      len = childNodes.length,
      result = '';

  for (var i = 0; i < len; i++) {
    if (childNodes[i].nodeType === 3)
      result += childNodes[i].nodeValue;
    else if (childNodes[i].nodeType === 1) 
      result += textContent(childNodes[i]);
  }

  return result;
}
Tyblitz
sumber
16
Juga perlu diperhatikan: innerTextakan mengubah <br>elemen menjadi karakter baris baru, sementara textContenthanya akan mengabaikannya. Jadi 2 kata dengan hanya <br>elemen di antara mereka (dan tanpa spasi) akan digabungkan ketika menggunakantextContent
skerit
5
Lalu apakah ada perbedaan ketika setter digunakan? Suka elem.textContent = 'foobar'vselem.innerText = 'foobar'
Franklin Yu
1
Perbedaan lain dalam perilaku antara innerTextdan textContent: Jika Anda mengubah text-transformelemen dengan CSS, itu akan mempengaruhi hasil 'innerText', tetapi bukan hasil textContent. Misalnya: innerTextdari <div style="text-transform: uppercase;">Hello World</div>akan "HELLO WORLD", sementara textContentakan "Hello World".
Kobi
25

textContent adalah satu-satunya yang tersedia untuk simpul teks:

var text = document.createTextNode('text');

console.log(text.innerText);    //  undefined
console.log(text.textContent);  //  text

Dalam node elemen, innerTextmengevaluasi elemen <br>, sementara textContentmengevaluasi karakter kontrol:

var span = document.querySelector('span');
span.innerHTML = "1<br>2<br>3<br>4\n5\n6\n7\n8";
console.log(span.innerText); // breaks in first half
console.log(span.textContent); // breaks in second half
<span></span>

span.innerText memberi:

1
2
3
4 5 6 7 8

span.textContent memberi:

1234
5
6
7
8

String dengan karakter kontrol (mis. Umpan baris) tidak tersedia dengan textContent, jika konten diatur dengan innerText. Dengan cara lain (atur karakter kontrol dengan textContent), semua karakter dikembalikan dengan innerTextdan textContent:

var div = document.createElement('div');
div.innerText = "x\ny";
console.log(div.textContent);  //  xy

Martin Wantke
sumber
20

Keduanya innerText& textContentdistandarisasi pada 2016. Semua Nodeobjek (termasuk node teks murni) miliki textContent, tetapi hanya HTMLElementobjek yang memilikinya innerText.

Sementara textContentbekerja dengan sebagian besar browser, itu tidak berfungsi pada IE8 atau sebelumnya. Gunakan polyfill ini untuk hanya bekerja pada IE8. Polyfill ini tidak akan berfungsi dengan IE7 atau yang lebih lama.

if (Object.defineProperty 
  && Object.getOwnPropertyDescriptor 
  && Object.getOwnPropertyDescriptor(Element.prototype, "textContent") 
  && !Object.getOwnPropertyDescriptor(Element.prototype, "textContent").get) {
  (function() {
    var innerText = Object.getOwnPropertyDescriptor(Element.prototype, "innerText");
    Object.defineProperty(Element.prototype, "textContent",
     {
       get: function() {
         return innerText.get.call(this);
       },
       set: function(s) {
         return innerText.set.call(this, s);
       }
     }
   );
  })();
}

The Object.definePropertymetode adalah availabe di IE9 atau naik, namun tersedia di IE8 untuk DOM objek saja.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent

Richard Hamilton
sumber
2
Berikut spesifikasi untuknya: w3.org/TR/DOM-Level-3-Core/core.html Juga tabel dukungan browser (sangat lama) ( webdevout.net/browser-support-dom#dom3core ) menyarankan, bahwa itu didukung untuk IE9 +, jadi untuk IE8 dan yang lebih lama, innerTextadalah teman Anda.
geekonaut
Sebenarnya, itu ide yang lebih baik untuk tidak mendukung IE8 atau menggunakan polyfill. Saya memposting polyfill di posting saya
Richard Hamilton
1
Bagaimana cara polyfill itu bekerja di IE8 ketika tidak mendukung Object.defineProperty()?
Runcing
2
mengapa Anda tidak memperbarui jawaban Anda? html.spec.whatwg.org/multipage/…
caub
3
Berikut adalah kutipan dari MDN tentang innerText - "Fitur ini awalnya diperkenalkan oleh Internet Explorer, dan secara resmi ditentukan dalam standar HTML pada 2016 setelah diadopsi oleh semua vendor browser utama."
chad
15

Bagi mereka yang mencari di Google pertanyaan ini dan tiba di sini. Saya merasa jawaban yang paling jelas untuk pertanyaan ini ada di dokumen MDN: https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent .

Anda dapat melupakan semua poin yang mungkin membingungkan Anda tetapi ingat 2 hal:

  1. Saat Anda mencoba mengubah teks, textContent biasanya properti yang Anda cari.
  2. Saat Anda mencoba mengambil teks dari beberapa elemen, innerTextkira-kira teks yang akan didapat pengguna jika mereka menyorot konten elemen dengan kursor dan kemudian disalin ke clipboard. Dan textContentmemberi Anda segalanya, terlihat atau tersembunyi, termasuk <script>dan <style>elemen.
Sebelah utara
sumber
11

textContent didukung oleh sebagian besar browser. Ini tidak didukung oleh ie8 atau sebelumnya, tetapi polyfill dapat digunakan untuk ini

Properti textContent menetapkan atau mengembalikan konten teks dari simpul yang ditentukan, dan semua turunannya.

Lihat http://www.w3schools.com/jsref/prop_node_textcontent.asp

Jeremy Ray Brown
sumber
0

textContent mengembalikan teks lengkap dan tidak peduli tentang visibilitas, sementara innerText tidak.

<p id="source">
    <style>#source { color: red; }</style>
    Text with breaking<br>point.
    <span style="display:none">HIDDEN TEXT</span>
</p>

Output dari textContent:

#source { color: red; } Text with breakingpoint. HIDDEN TEXT

Output dari innerText (perhatikan bagaimana innerText menyadari akan adanya tag <br>, dan abaikan elemen tersembunyi):

Text with breaking point.
Milan Chandro
sumber
Di IE11, perilaku innerText sama dengan perilaku dari textContent.
Sebastian
0

Terlepas dari semua perbedaan yang disebutkan dalam jawaban lain, berikut ini satu lagi yang baru saya temukan:

Meskipun innerTextproperti dikatakan telah distandarisasi sejak 2016, properti ini menunjukkan perbedaan antara browser: Mozilla mengabaikan karakter U + 200E dan U + 200F ("lrm" dan "rlm") innerText, sementara Chrome tidak.

console.log(document.getElementById('test').textContent.length);
console.log(document.getElementById('test').innerText.length);
<div id="test">[&#x200E;]</div>

Firefox melaporkan 3 dan 2, Chrome melaporkan 3 dan 3.

Belum yakin apakah ini bug (dan jika demikian, di browser mana) atau hanya salah satu dari ketidakcocokan unik yang harus kita jalani.

Tuan Lister
sumber
-1

innerHTML akan mengeksekusi bahkan tag HTML yang mungkin berbahaya menyebabkan segala jenis serangan injeksi sisi klien seperti XSS berbasis DOM. Berikut ini cuplikan kode:

<!DOCTYPE html>
<html>
    <body>
        <script>
            var source = "Hello " + decodeURIComponent("<h1>Text inside gets executed as h1 tag HTML is evaluated</h1>");  //Source
            var divElement = document.createElement("div");
            divElement.innerHTML = source;  //Sink
            document.body.appendChild(divElement);
        </script>
    </body>
</html>

Jika Anda menggunakan .textContent, itu tidak akan mengevaluasi tag HTML dan mencetaknya sebagai String.

<!DOCTYPE html>
<html>
    <body>
        <script>
            var source = "Hello " + decodeURIComponent("<h1>Text inside will not get executed as HTML</h1>");  //Source
            var divElement = document.createElement("div");
            divElement.textContent = source;  //Sink
            document.body.appendChild(divElement);
        </script>
    </body>
</html>

Referensi: https://www.scip.ch/en/?labs.20171214

Ashwath Halemane
sumber