Разница между textContent и innerText

В чем разница между textContent а также innerText в JavaScript?

Могу ли я использовать textContent следующее:

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

10 ответов

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

  1. innerText был нестандартным, в то время как textContent был стандартизирован ранее.
  2. innerText возвращает видимый текст, содержащийся в узле, в то время как textContent возвращает полный текст Например, на следующем HTML <span>Hello <span style="display: none;">World</span></span>, innerText вернет "Привет", а textContent вернет "Hello World". Более полный список различий см. В таблице по адресу http://perfectionkills.com/the-poor-misunderstood-innerText/.
  3. В следствии, innerText гораздо более требователен к производительности: для получения результата требуется информация макета.

Обходной путь для 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;
}

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";

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

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

Вы можете забыть все моменты, которые могут вас смущать, но помните 2 вещи:

  1. Когда вы пытаетесь изменить текст, textContent обычно это свойство, которое вы ищете.
  2. Когда вы пытаетесь получить текст из какого-то элемента, innerText приблизительно соответствует тексту, который получит пользователь, если он выделит содержимое элемента курсором и затем скопирует в буфер обмена. А также textContent дает вам все, видимое или скрытое, в том числе <script> а также <style> элементы.

Разница в том, что innerText является нестандартным и textContent стандартизирован. Вот официальное предупреждение для innerText.

Эта функция является нестандартной и не соответствует стандартам. Не используйте его на производственных сайтах, выходящих в Интернет: он не будет работать для каждого пользователя. Также могут быть большие несовместимости между реализациями, и поведение может измениться в будущем.

В то время как textContent работает с большинством браузеров, он не работает на ie8 или ранее. Используйте этот polyfill, чтобы он работал только в IE8. Этот polyfill не будет работать с 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 Метод доступен в 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

textContent поддерживается большинством браузеров. Он не поддерживается ie8 или более ранней версией, но для этого можно использовать polyfill

Свойство textContent устанавливает или возвращает текстовое содержимое указанного узла и всех его потомков.

См. http://www.w3schools.com/jsref/prop_node_textcontent.asp

Помимо всех различий, которые были названы в других ответах, вот еще один, который я обнаружил совсем недавно:

Хотя 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.

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

Text Content возвращает полный текст и не заботится о видимости, в отличие от innerText.

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

Вывод textContent:

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

Вывод innerText (обратите внимание, как innerText распознает такие теги, как <br>, и игнорирует скрытый элемент):

Text with breaking point.

Еще одно полезное поведение innerText по сравнению с textContent заключается в том, что символы новой строки и несколько пробелов рядом друг с другом будут отображаться только как один пробел, что может быть проще для сравнения строки.

Но в зависимости от того, что ты хочешь, firstChild.nodeValue может хватит.

document.querySelector('h1').innerText / HTML / textContent

.querySelector('h1').innerText - дает нам текст внутри. Он чувствителен к тому, что в настоящее время отображается, или к скрытому персоналу игнорируется.

.querySelector('h1').innertextContent - это похоже на innerText, но его не волнует, что отображается или что на самом деле отображается пользователю. Это все покажет.

.querySelector('h1'). внутренний HTML = Будет работать * - получает полное содержимое, включая имена тегов.

Inner HTML будет выполнять даже теги 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/en/?labs.20171214

Другие вопросы по тегам