Há muitos caminhos para usar essas propriedades para incluir conteúdo no DOM com JavaScript. Existem quatro maneiras de definir o conteúdo de um elemento HTML no DOM: innerHTML
, innerText
, textContent
e a função setHTML()
introduzida recentemente pela Sanitizer API
.
Mas neste artigo abordaremos as três propriedades mais populares em JavaScript, já a função setHTML() dedicaremos um post específico para ela.
innerHTML
A propriedade innerHTML
define e retorna o conteúdo de um elemento com novo conteúdo HTML ou XML, isso mesmo você pode manipular um XML.
A propriedade tem um JavaScript serializado, definindo o valor de innerHTML
você irá substituir todo o conteúdo do elemento selecionado, incluindo os filhos. A propriedade pode ser utilizada para analisar o conteúdo HTML. Mas pode trazer riscos a sua aplicação caso um código malicioso seja injetado na sua aplicação.
name = "<script>alert('Isso poderia ser um ataque!')</script>";
el.innerHTML = name;
// considerando que el é um elemento no DOM
// Essa tag script pode executar qualquer código
Code language: HTML, XML (xml)
Não pense que isso está limitado apenas a tag script podemos executar javascript de outras maneiras, por exemplo:
const name = "<img src='x' onerror='alert("Isso poderia ser um ataque!")'>";
el.innerHTML = name; // o alerta é executado
Code language: JavaScript (javascript)
Além dos problemas de segurança com innerHTML
pode trazer outros problemas de desempenho com a re-renderização desnecessária do DOM. Acessibilidade é outro problema, pois leitores de tela podem ter dificuldades em ler o conteúdo criado dinamicamente.
Por esse motivo, é recomendável que, em vez de innerHTML
, você use:
- Element.setHTML() nova API que permite a manipulação de HTML sem o risco de injeção de script no DOM.
- Node.textContent propriedade que permite inserir texto simples, pois isso o insere como texto bruto em vez de analisá-lo como HTML.
Diferença entre innerHTML e setHTML()
Sanitizer API está disponível em apenas 40% dos navegadores(setembro 2022), mas ela irá trazer muitos benefícios em termos de manipulação de HTML, por exemplo:
HTML
<h1 class="title">Cadastro nacional 🇧🇷</h1>
<h3>Nome:</h3>
<input id="input-inner" type="text" />
<h3>Mensagem:</h3>
<textarea id="input-set" type="text" rows="6"></textarea>
<button id="save-btn" class="btn--remix">
Cadastrar
</button>
<p id="output-inner"></p>
<p id="output-set"></p>
Code language: HTML, XML (xml)
JavaScript
const outputInner = document.getElementById("output-inner");
const outputset = document.getElementById("output-set");
const inputInner = document.getElementById("input-inner");
const inputSet = document.getElementById("input-set");
const saveBtn = document.getElementById("save-btn");
saveBtn.addEventListener("click", () => {
outputInner.innerHTML = inputInner.value;
const mySanitizer = new Sanitizer();
outputset.setHTML(inputSet.value, { sanitizer: new Sanitizer() });
});
Code language: JavaScript (javascript)
No exemplo acima o código HTML é renderizado, mas o alert
inserido na imagem será removido, caso adicione o mesmo código no primeiro campo que usar innerHTML
o alert
será disparado assim sendo uma falha de segurança.
textContent
textContent
é uma propriedade que fornece o texto contido num nó de DOM. Esse texto inclui todos os nós de texto, bem como os nós de comentário.
Atenção: Assim como innerHTML
, definir textContent
num nó remove todos os filhos do nó e os substitui por um único nó de texto com o valor de string
fornecido.
Diferenças entre textContent e innerHTML
Como já abordamos anteriormente, o Element.innerHTML
retorna HTML, como o seu nome indica. Às vezes, as pessoas usam innerHTML
para recuperar ou escrever texto num elemento, mas textContent
além de impedir ataques XSS, ele tem melhor desempenho porque o seu valor não é analisado como HTML.
Diferenças entre textContent e innerHTML
Não se confunda com as diferenças entre Node.textContent
e HTMLElement.innerText.
Embora os nomes pareçam semelhantes, existem diferenças importantes:
textContent
obtém o conteúdo de todos os elementos, incluindo os elementos<script>
e<style>
. Em contraste,innerText
mostra apenas elementos “legíveis para humanos”.textContent
retorna todos os elementos no nó. Em contraste,innerText
está ciente do estilo e não retornará o texto de elementos “ocultos”.- Além disso, como
innerText
considera os estilos CSS, a leitura do valor deinnerText
aciona um reflow para garantir estilos computados atualizados. (Os refluxos podem ser computacionalmente caros e, portanto, devem ser evitados quando possível.) - Tanto
textContent
quantoinnerText
removem nós filho quando alterados, mas alterarinnerText
no Internet Explorer (versão 11 e inferior) também destrói permanentemente todos os nós de texto descendentes. É impossível inserir os nós novamente em qualquer outro elemento ou no mesmo elemento após fazê-lo.
innerText
A propriedade innerText
da interface HTMLElement
representa o conteúdo de texto renderizado de um nó e os seus descendentes.
Como um getter
, ele aproxima o texto que o usuário obteria se destacasse o conteúdo do elemento com o cursor e o copiasse para a área de transferência. Como um setter
, isso substituirá os filhos do elemento pelo valor fornecido, convertendo qualquer quebra de linha em elementos. Por exemplo, no código a seguir:
<h1 class="title">Fonte do conteúdo 🇧🇷</h1>
<p id="source">
<style>
#source {
color: red;
}
#text {
text-transform: uppercase;
}
</style>
<span id="text">
Veja como<br />
podemos comprar<br />
casas.
</span>
<span style="display: none">em dinheiro</span>
</p>
<h3>Resultado do textContent:</h3>
<textarea id="textContentOutput" rows="6" cols="30" readonly>...</textarea
>
<h3>Resultado do innerText:</h3>
<textarea id="innerTextOutput" rows="6" cols="30" readonly></textarea>
Code language: HTML, XML (xml)
const source = document.getElementById("source");
const textContentOutput = document.getElementById("textContentOutput");
const innerTextOutput = document.getElementById("innerTextOutput");
textContentOutput.value = source.textContent;
innerTextOutput.value = source.innerText;
Code language: JavaScript (javascript)
Quando rodamos o código temos o seguinte resultado:
Essa foi uma introdução sobre essas as três formas de manipular o dom com as propriedades mais antigas do JavaScript, em breve estarei falando um pouco sobre sanitizer API, mas se você deste conteúdo confira os artigos relacionados a JavaScript:
- Diferença entre Arrow function e traditional function em JavaScript
- Trabalhando com Promises JavaScript
- localStorage: Armazenando dados com JavaScript
Referência: MDN
Deixe um comentário