Разница между textContent и innerText
В чем разница между textContent
а также innerText
в JavaScript?
Могу ли я использовать textContent
следующее:
var logo$ = document.getElementsByClassName('logo')[0];
logo$.textContent = "Example";
10 ответов
Ни один из других ответов не дает полного объяснения, отсюда и этот. Ключевые различия между innerText
а также textContent
очень хорошо изложены в блоге Келли Нортон: innerText vs. textContent. Ниже вы можете найти резюме:
innerText
был нестандартным, в то время какtextContent
был стандартизирован ранее.innerText
возвращает видимый текст, содержащийся в узле, в то время какtextContent
возвращает полный текст Например, на следующем HTML<span>Hello <span style="display: none;">World</span></span>
,innerText
вернет "Привет", аtextContent
вернет "Hello World". Более полный список различий см. В таблице по адресу http://perfectionkills.com/the-poor-misunderstood-innerText/.- В следствии,
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 вещи:
- Когда вы пытаетесь изменить текст,
textContent
обычно это свойство, которое вы ищете. - Когда вы пытаетесь получить текст из какого-то элемента,
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/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">[‎]</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>