Różnica między textContent a innerText


157

Jaka jest różnica między textContenti innerTextw JavaScript?

Czy mogę użyć textContentw następujący sposób:

var logo$ = document.getElementsByClassName('logo')[0];
logo$.textContent = "Example";

3
Są takie same, ale niektóre przeglądarki obsługują jedną, a inne drugą.
Pointy

@Pointy jaki jest ten, który obsługują wszystkie przeglądarki?
Yehia Awad


4
@Pointy, zapoznaj się z wpisem na blogu, na który wskazałem. Twoje stwierdzenie jest nieprawidłowe, jest różnica.
Tyblitz

3
innerTexti textContentzdecydowanie nie są takie same. Wystąpienie pustych przestrzeni w zawartości węzła spowoduje, że dwie właściwości będą dawały inną zawartość, podobnie jak brelementy i inne elementy potomne renderowane na poziomie bloków.
rano

Odpowiedzi:


211

Żadnej z pozostałych odpowiedzi nie udaje się dostarczyć pełnego wyjaśnienia, stąd ta. Kluczowe różnice między innerTexti textContentsą bardzo dobrze opisane w poście Kelly Norton: innerText a textContent . Poniżej znajduje się podsumowanie:

  1. innerTextbył niestandardowy, podczas gdy textContentzostał ustandaryzowany wcześniej.
  2. innerTextzwraca widoczny tekst zawarty w węźle, a textContentzwraca pełny tekst. Na przykład, następujący kod HTML <span>Hello <span style="display: none;">World</span></span>, innerTextpowróci „Hello”, podczas gdy textContentpowróci „Hello World”. Bardziej szczegółową listę różnic można znaleźć w tabeli pod adresem http://perfectionkills.com/the-poor-misunderstood-innerText/ (dalsze czytanie pod adresem „innerText” działa w przeglądarce IE, ale nie w przeglądarce Firefox ).
  3. W rezultacie innerTextjest znacznie bardziej obciążony wydajnością: wymaga informacji o układzie, aby zwrócić wynik.
  4. innerTextjest definiowany tylko dla HTMLElementobiektów, natomiast textContentjest definiowany dla wszystkich Nodeobiektów.

Obejście problemu textContentw IE8- obejmowałoby funkcję rekurencyjną używającą nodeValuena całym childNodesokreślonym węźle, oto próba wypełnienia 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;
}

16
Warto również zauważyć: innerTextzamieni <br>elementy w znaki nowej linii, a textContentpo prostu je zignoruje. Tak więc 2 słowa zawierające tylko <br>element między nimi (bez spacji) zostaną połączone podczas używaniatextContent
skerit

5
Czy jest więc jakaś różnica, kiedy używa się ustawiacza? Like elem.textContent = 'foobar'vselem.innerText = 'foobar'
Franklin Yu

1
Kolejna różnica w zachowaniu między innerTexti textContent: Jeśli zmienisz text-transformelement elementu za pomocą CSS, wpłynie to na wynik „innerText”, ale nie na wynik textContent. Na przykład: innerTextz <div style="text-transform: uppercase;">Hello World</div>będzie „HELLO WORLD”, a textContent„Hello World”.
Kobi

25

textContent jest jedynym dostępnym dla węzłów tekstowych:

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

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

W węzłach elementów innerTextocenia elementy <br>, a textContentznaki sterujące:

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 daje:

1
2
3
4 5 6 7 8

span.textContent daje:

1234
5
6
7
8

Ciągi ze znakami sterującymi (np. Nowe wiersze) nie są dostępne w przypadku textContent, gdy treść została ustawiona za pomocą innerText. W drugą stronę (ustaw znaki sterujące z textContent), wszystkie znaki są zwracane zarówno z, jak innerTexti textContent:

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


20

Oba innerTexti textContentsą znormalizowane od 2016 r. Wszystkie Nodeobiekty (w tym węzły czystego tekstu) mają textContent, ale tylko HTMLElementobiekty mają innerText.

Chociaż textContentdziała z większością przeglądarek, nie działa w IE8 lub starszym. Użyj tego wypełnienia, aby działał tylko w przeglądarce IE8. Ten wypełniacz nie będzie działał z IE7 lub starszymi wersjami.

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);
       }
     }
   );
  })();
}

Object.definePropertyMetoda jest dostępnej w IE9 lub w górę, jednak jest ona dostępna w IE8 dla DOM tylko obiekty.

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


2
Oto jego specyfikacja: w3.org/TR/DOM-Level-3-Core/core.html Również (bardzo stara) tabela obsługi przeglądarek ( webdevout.net/browser-support-dom#dom3core ) sugeruje, że jest obsługiwany dla IE9 +, więc dla IE8 i starszych innerTextjest twoim przyjacielem.
geekonaut

Właściwie lepiej nie obsługiwać ie8 lub używać polyfill. Opublikowałem polyfill w moim poście
Richard Hamilton

1
Jak ten polyfill może działać w IE8, jeśli nie był obsługiwany Object.defineProperty()?
Pointy

2
dlaczego nie zaktualizujesz odpowiedzi? html.spec.whatwg.org/multipage/ ...
caub

3
Oto cytat z MDN dotyczący innerText - „Ta funkcja została pierwotnie wprowadzona przez przeglądarkę Internet Explorer i została formalnie określona w standardzie HTML w 2016 r. Po przyjęciu jej przez wszystkich głównych dostawców przeglądarek”.
czad

15

Dla tych, którzy wygooglowali to pytanie i przybyli tutaj. Czuję, że najbardziej klarowna odpowiedź na to pytanie znajduje się w dokumencie MDN: https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent .

Możesz zapomnieć o wszystkich punktach, które mogą Cię zmylić, ale pamiętaj o dwóch rzeczach:

  1. Kiedy próbujesz zmienić tekst, textContentjest to zwykle właściwość, której szukasz.
  2. Kiedy próbujesz pobrać tekst z jakiegoś elementu, innerTextprzybliża tekst, który uzyskałby użytkownik, gdyby podświetlił zawartość elementu kursorem, a następnie skopiował do schowka. I textContentdaje wszystko, widoczne lub ukryte, w tym elementy <script>i <style>.


0

textContent zwraca pełny tekst i nie dba o widoczność, podczas gdy innerText tak.

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

Wyjście tekstu Treść:

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

Dane wyjściowe innerText (zwróć uwagę, że innerText rozpoznaje tagi, takie jak <br>i ignoruje ukryty element):

Text with breaking point.

W IE11 zachowanie innerText jest takie samo jak zachowanie textContent.
Sebastian

0

Oprócz wszystkich różnic, które zostały wymienione w innych odpowiedziach, oto kolejna, którą odkryłem dopiero niedawno:

Chociaż innerTextmówi się, że właściwość jest znormalizowana od 2016 r., Wykazuje różnice między przeglądarkami: Mozilla ignoruje znaki U + 200E i U + 200F („lrm” i „rlm”) w innerText, podczas gdy Chrome nie.

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

Firefox zgłasza 3 i 2, Chrome raporty 3 i 3.

Nie jestem jeszcze pewien, czy jest to błąd (a jeśli tak, w której przeglądarce), czy tylko jedna z tych dziwacznych niezgodności, z którymi musimy żyć.


-1

innerHTML wykona nawet tagi HTML, które mogą być niebezpieczne, powodując wszelkiego rodzaju ataki typu client-side injection, takie jak XSS oparty na DOM. Oto fragment kodu:

<!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>

Jeśli używasz .textContent, nie oceni znaczników HTML i nie wydrukuje go jako 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>

Źródła: https://www.scip.ch/en/?labs.20171214

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.