Reputation: 718
'use strict';
function injectCharacters(){
var paragraph = document.getElementById( 'paragraph' ),
text = paragraph.innerHTML,
ary = text.split( '' ),
i = 1;
paragraph.innerHTML = '';
for ( i; i <= 52 ; i++ ){
window.setTimeout(
(
function( i ){
return function(){
paragraph.innerHTML += ary[ i ];
}
}
)
( i ), i * 100
)
}
}
injectCharacters();
* {
margin: 0;
}
html,
body {
overflow: hidden;
height: 100%;
}
body {
display: flex;
font-family: Arial;
}
p {
margin: auto;
}
.mtx-3d {
transform:
perspective( 10rem )
matrix3D(
1, 0.25, 0.5, 0.0075,
0.25, 2, 2, 0.02,
1, 2, 3, 4,
1, 2, 3, 0.75
)
}
<p id="paragraph" class="mtx-3d">
So. Yeah I mean. <br>I've been thinking <br>A lot
</p>
In the snippet above the line breaks are literal in the output. I want an actual line-break to display instead of seeing <br>
. How can I solve this simple problem?
I suspect it has something to do with me breaking up every character into a value housed in an array then outputting that back to the paragraph element but I could be wrong.
Upvotes: 1
Views: 971
Reputation: 42746
You will need to split the html element away into it's own element so it will end up like
["a,"b","c","<br>","d","e","f"]
You could for instance loop over each node of the element, split all textNodes and when it sees a element just add the element's html.
Array.from(paragraph.childNodes).forEach(function(node){
if(node.nodeType == 3){
ary.push( ...node.textContent.split('') );
} else {
ary.push( node.outerHTML );
}
});
Note this example will probably only work well with elements that don't have sub elements like a div with children. And if your paragraph ends up containing more complex html than just <br>
it will probably need refactoring.
Demo
'use strict';
function start(){
var paragraph = document.getElementById( 'paragraph' ),
ary = [];
Array.from(paragraph.childNodes).forEach(function(node){
if(node.nodeType == 3){
ary.push( ...node.textContent.split('') );
} else {
ary.push( node.outerHTML );
}
});
paragraph.innerHTML = '';
for ( let i=1; i < ary.length ; i++ ){
window.setTimeout(function(){
paragraph.innerHTML += ary[ i ];
}, i * 100);
}
}
start();
* {
margin: 0;
}
html,
body {
overflow: hidden;
height: 100%;
}
body {
display: flex;
font-family: Arial;
}
p {
margin: auto;
}
.mtx-3d {
transform:
perspective( 10rem )
matrix3D( 1, 0.25, 0.5, 0.0075, 0.25, 2, 2, 0.02, 1, 2, 3, 4, 1, 2, 3, 0.75 )
}
<p id="paragraph" class="mtx-3d">
So. Yeah I mean. <br>I've been thinking <br>A lot
</p>
Upvotes: 1
Reputation: 802
This seemed to work for me:
'use strict';
function injectCharacters() {
var paragraph = document.getElementById('paragraph'),
text = paragraph.innerHTML,
i = 0;
paragraph.innerHTML = '';
while (i < text.length) {
var c = text.charAt(i);
if (text.slice(i, i + 4) == '<br>') {
c = text.slice(i, i + 5);
}
window.setTimeout(function( c ) {
return function() {
paragraph.innerHTML += c;
}
}( c ), i * 100
);
i += c.length;
}
}
injectCharacters();
I basically re-worked the logic to check for
'<br>'
.
If found, append it plus the next character. This seems to preserve the
<br>
element in the html.
Upvotes: 1
Reputation: 137171
By appending a new character every time, with innerHTML +=
the browser will convert <
and >
characters as HTMLEntities, and thus the sequence <br>
will be converted to <br>
:
para.innerHTML += '<';
console.log(para.innerHTML);
<p id="para"></p>
To fix it, you can set the current content every time with innerHTML = text.slice(0, i);
.
'use strict';
function injectCharacters(){
var paragraph = document.getElementById( 'paragraph' ),
text = paragraph.innerHTML,
i = 1;
paragraph.innerHTML = '';
for ( i; i <= 52 ; i++ ){
window.setTimeout(
(
function( i ){
return function(){
paragraph.innerHTML = text.slice(0,i);
}
}
)
( i ), i * 100
)
}
}
injectCharacters();
* {
margin: 0;
}
html,
body {
overflow: hidden;
height: 100%;
}
body {
display: flex;
font-family: Arial;
}
p {
margin: auto;
}
.mtx-3d {
transform:
perspective( 10rem )
matrix3D(
1, 0.25, 0.5, 0.0075,
0.25, 2, 2, 0.02,
1, 2, 3, 4,
1, 2, 3, 0.75
)
}
<p id="paragraph" class="mtx-3d">
So. Yeah I mean. <br>I've been thinking <br>A lot
</p>
And if you don't want to show <
, <b
and <br
, you could replace it in your string before hand to some unlikely to show up character, and replace it again when setting :
'use strict';
function injectCharacters(){
var paragraph = document.getElementById( 'paragraph' ),
text = paragraph.innerHTML.replace(/<br>/g, '\u10FF'),
i = 1;
paragraph.innerHTML = '';
for ( i; i <= 52 ; i++ ){
window.setTimeout(
(
function( i ){
return function(){
paragraph.innerHTML = text.slice(0,i).replace(/\u10FF/g, '<br>');
}
}
)
( i ), i * 100
)
}
}
injectCharacters();
* {
margin: 0;
}
html,
body {
overflow: hidden;
height: 100%;
}
body {
display: flex;
font-family: Arial;
}
p {
margin: auto;
}
.mtx-3d {
transform:
perspective( 10rem )
matrix3D(
1, 0.25, 0.5, 0.0075,
0.25, 2, 2, 0.02,
1, 2, 3, 4,
1, 2, 3, 0.75
)
}
<p id="paragraph" class="mtx-3d">
So. Yeah I mean. <br>I've been thinking <br>A lot
</p>
Upvotes: 1