Різниця між textContent і innerText


157

Яка різниця між JavaScript textContentта innerTextJavaScript?

Чи можу я використовувати textContentнаступне:

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

3
Вони однакові, але деякі браузери підтримують одне, а інше - інше.
Pointy

@Pointy, що таке той, який підтримують усі браузери?
Yehia Awad

6
Хороший блог про нього
Tyblitz

4
@Pointy, будь ласка, зверніться до публікації в блозі, на яку я вказав. Ваше твердження невірне, є різниця.
Тиблиця

3
innerTextі textContentрішуче не однакові. Виникнення білого простору у вмісті вузлів призведе до того, що обидві властивості дають різний вміст, а також виникнення brелементів та інших блокових рівнів, що надаються нащадкам.
amn

Відповіді:


211

Жоден з інших відповідей не в змозі дати повне пояснення, звідси і цей. Ключові відмінності між innerTextта textContentдуже добре окреслені у пості на блозі Келлі Нортон: innerText vs. textContent . Нижче ви знайдете резюме:

  1. innerTextбув нестандартним, тоді як textContentбув стандартизований раніше.
  2. innerTextповертає видимий текст, що міститься у вузлі, а textContentповертає повний текст. Наприклад, на наступний HTML <span>Hello <span style="display: none;">World</span></span>, innerTextбуде повертати «Hello», в той час як textContentповертатиме «Hello World». Більш повний перелік відмінностей дивіться у таблиці на веб-сторінці http://perfectionkills.com/the-poor-misunderpted-innerText/ (подальше читання у "innerText" працює в IE, але не у Firefox ).
  3. Як результат, innerTextце набагато більш висока продуктивність: для повернення результату потрібна інформація про розташування.
  4. innerTextвизначається лише для HTMLElementоб'єктів, тоді textContentяк визначається для всіх Nodeоб'єктів.

textContentВирішення проблеми в IE8- передбачало б рекурсивну функцію, що використовується nodeValueна всьому childNodesвказаному вузлі, ось спробу поліфауни:

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
Також варто відзначити: innerTextперетворить <br>елементи в символи нового рядка, при textContentцьому просто їх ігнорує. Тож 2 слова з лише <br>елементом між ними (і без пробілів) будуть об'єднані при використанніtextContent
skerit

5
Тоді чи є різниця, коли використовується сетер? Like elem.textContent = 'foobar'vselem.innerText = 'foobar'
Franklin Yu

1
Ще одна різниця в поведінці між innerTextі textContent: Якщо ви зміните text-transformелемент за допомогою CSS, це вплине на результат 'innerText', але не на результат textContent. Наприклад: innerTextof <div style="text-transform: uppercase;">Hello World</div>буде "HELLO WORLD", тоді як textContentбуде "Hello World".
Кобі

25

textContent є єдиним доступним для текстових вузлів:

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

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

У елементах вузлів innerTextоцінює елементи елементів, а textContentконтрольні символи:

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 дає:

1
2
3
4 5 6 7 8

span.textContent дає:

1234
5
6
7
8

Рядки з контрольними символами (наприклад, канали рядків) недоступні textContent, якщо вміст встановлено за допомогою innerText. З іншого боку (встановити контрольні символи за допомогою textContent), всі символи повертаються як innerTextі textContent:

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


20

Обидва innerText& textContentстандартизовані станом на 2016 рік. Усі Nodeоб'єкти (включаючи чисті текстові вузли) мають textContent, але мають лише HTMLElementоб'єкти innerText.

Хоча textContentпрацює з більшістю браузерів, він не працює на IE8 або раніше. Використовуйте цей полів, щоб він працював лише на IE8. Цей поліфіл не працюватиме з IE7 або раніше.

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.definePropertyМетод Availabe в IE9 або вгору, проте він доступний в IE8 для DOM тільки об'єкти.

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
Ось і специфікація для цього: w3.org/TR/DOM-Level-3-Core/core.html Також (дуже стара) таблиця підтримки браузера ( webdevout.net/browser-support-dom#dom3core ) говорить про те, що він підтримується для IE9 +, тому для IE8 та старших innerText- ваш друг.
geekonaut

Насправді, краща ідея або не підтримувати ie8, або використовувати polyfill. Я розмістив поліфайл у своєму дописі
Річард Гамільтон

1
Як може ця поліфазова заправка працювати в IE8, коли вона не підтримує Object.defineProperty()?
Pointy

2
чому ви не оновите свою відповідь? html.spec.whatwg.org/multipage/…
кауб

3
Ось цитата з MDN про innerText - "Ця функція була спочатку запроваджена Internet Explorer і була офіційно визначена в стандарті HTML у 2016 році після того, як її прийняли всі основні постачальники браузерів."
чад

15

Для тих, хто гуглив це питання і прибув сюди. Я вважаю, що найбільш чітка відповідь на це запитання - у документі MDN: https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent .

Ви можете забути всі моменти, які можуть вас бентежити, але запам'ятати дві речі:

  1. Коли ви намагаєтесь змінити текст, textContentзазвичай це властивість, яку ви шукаєте.
  2. Коли ви намагаєтеся захопити текст з якогось елемента, innerTextнаближає текст, який отримав би користувач, якби виділив вміст елемента курсором, а потім скопіював у буфер обміну. І textContentдає вам все, видиме або приховане, включаючи <script>і <style>елементи.

11

textContent підтримується більшістю браузерів. Він не підтримується ie8 або раніше, але поліфіл може бути використаний для цього

Властивість textContent встановлює або повертає текстовий вміст зазначеного вузла та всіх його нащадків.

Див. Http://www.w3schools.com/jsref/prop_node_textcontent.asp


0

textContent повертає повний текст і не піклується про видимість, тоді як InternalText робить.

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

Вихід з тексту:

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

Виведення InternalText (зверніть увагу на те, як innerText знає такі теги, як <br>ігнорує прихований елемент):

Text with breaking point.

У IE11 поведінка innerText така ж, як і в textContent.
Себастьян

0

Окрім усіх відмінностей, які були названі в інших відповідях, ось ще одна, яку я виявив зовсім недавно:

Незважаючи на те, що innerTextвластивість стандартизована з 2016 року, вона демонструє відмінності між браузерами: Mozilla ігнорує символи U + 200E та U + 200F ("lrm" і "rlm") innerText, а Chrome - ні.

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

Firefox повідомляє 3 і 2, а Chrome 3 і 3.

Не впевнений, чи це помилка (і якщо так, то в якому браузері) чи просто одна з тих химерних несумісностей, з якими нам доводиться жити.


-1

innerHTML виконуватиме навіть теги HTML, які можуть бути небезпечними, спричиняючи будь-яку атаку ін'єкції на стороні клієнта, як XSS на основі DOM. Ось фрагмент коду:

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

Якщо ви використовуєте .textContent, він не буде оцінювати теги HTML і друкувати його як 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>

Довідка: https://www.scip.ch/uk/?labs.20171214

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.