This is because the split()
divides the <br>
also, what you can do is use a regular expression, so instead of split()
you can use String.prototype.match
, see how the array looks after:
console.log("a b c d <br> foo bar <br> asd".match(/<\w+?>|./g))
The first part of the expression is to pick up the tags <\w+?>
and the .
after the pipe (|
) is to pick up any other character (up to spaces.
However you could also make a for()
well designed to join characters when it is a tag, navigating character by character, and not even need split, for example (see comments within code):
const elemento = document.querySelector("p");
const texto = elemento.innerHTML;
let hasOpenTag = false;
let tmpTag;
//Limpa o campo
elemento.innerHTML = '';
for (let i = 0, j = texto.length; i < j; i++) {
let letra = texto[i];
/*
Se o caractere for "<" então executa o continue;
para que o setTimeout não seja executado e armazenará
os próximos caracteres até encontrar o ">"
*/
if (letra === '<') {
tmpTag = letra;
hasOpenTag = true;
continue;
}
/*
Se encontrar o ">" e antes dele teve um "<"
então junta a tag toda na variável tmpTag e irá
adicionar ao setTimeout
*/
if (hasOpenTag && letra === '>') {
letra = tmpTag + letra;
hasOpenTag = false;
}
/*
Se a variavel hasOpenTag for true irá armazenar
todos próximos caracteres para formar a tag, até
encontrar o ">" (da if anterior)
adicionar ao setTimeout
*/
if (hasOpenTag) {
tmpTag += letra;
continue;
}
setTimeout(() => elemento.innerHTML += letra, 75 * i);
}
p::after {
content: "|";
margin-left: 5px;
opacity: 1;
animation: pisca 0.7s infinite;
}
@keyframes pisca {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
<p>Olá mundo <br> Olá Universo <br> Olá Vida</p>
Dennis, I edited my answer with an example without regex and without split.
– Guilherme Nascimento