Reputation: 101
I have two elements with typing effect using javascript, every element has its own function to make the typing effect, the problem is the two texts get displayed incompletely, but when I comment out one of the two functions all of the characters get displayed. And here is my index.js:
const h1Txt = 'this is h1';
const headerP = 'this is paragraph!';
let i = 0;
window.addEventListener('load', function() {
console.log('typing');
executeAsynchronously([typeWriter, typeWriter2], 100);
});
function executeAsynchronously(functions, timeout) {
for (var i = 0; i < functions.length; i++) {
setTimeout(functions[i], timeout);
}
}
// The typewriter method for h1
function typeWriter() {
if (i < h1Txt.length) {
document.getElementById('h1-text').innerHTML += h1Txt.charAt(i);
i++;
setTimeout(typeWriter, 100);
}
}
// The typewriter method for p
function typeWriter2() {
if (i < headerP.length) {
document.getElementById('p-text').innerHTML += headerP.charAt(i);
i++;
setTimeout(typeWriter2, 100);
}
}
<h1 class="text-floating" id="h1-text"></h1>
<p id="p-text"></p>
Upvotes: 1
Views: 361
Reputation: 13078
Having the same i
global variable for both functions causes i
takes unexpected values. You can create one function to control the typing, and i
will be in the type
function's scope:
const h1Txt = "this is h1";
const headerP = "this is paragraph!";
window.addEventListener("load", function() {
executeAsynchronously([
[h1Txt, "h1-text", 100],
[headerP, "p-text", 100]
]);
});
function executeAsynchronously(texts) {
texts.forEach(args => type(...args));
}
function type(text, id, delay) {
const node = document.getElementById(id);
for (let i = 0; i < text.length; i++) {
setTimeout(() => {
node.textContent += text.charAt(i);
}, i * delay);
}
}
<h1 class="text-floating" id="h1-text"></h1>
<p id="p-text"></p>
Upvotes: 1
Reputation: 485
You are using the same 'i' for both, the characters are gets missed out because of that. I've simplified the code a bit, here'a working sample in codepen:
window.addEventListener('load', function() {
console.log('typing');
executeAsynchronously([
typeText('h1-text', 'this is h1'),
typeText('p-text', 'this is paragraph!'),
], 100);
});
function executeAsynchronously(functions, timeout) {
for (var i = 0; i < functions.length; i++) {
setTimeout(functions[i], timeout);
}
}
function typeText(elementId, text) {
let idx = 0;
const element = document.getElementById(elementId);
let interval;
interval = setInterval(() => {
element.innerHTML += text.charAt(idx);
idx++;
if (idx == text.length) {
clearInterval(interval);
}
}, 100);
}
<h1 class="text-floating" id="h1-text"></h1>
<p id="p-text"></p>
Upvotes: 0
Reputation: 5999
The issue in your code is that, you are referring to the same variable i
which is declared at the global level in both of your typeWriter
functions.
By the time one of the typeWriter
function gets executed, i
value will be incremented and since both the typeWriter
functions are referring to the same one of the character is not getting displayed in the output.
For eg.,
typeWriter1
gets executed first at the end of the function execution i
will be 1
. And in the output it'll print t
in the h1Txt
text.typeWriter2
gets its turn and getting executed, now this function is also referring to same i
whose value is 1
. So, it'll not print t
in headerP
text.So, the output is not getting displayed as expected.
Below is one of the ways you can fix this issue i.e., by using two different variables which will be referred in typeWriter
functions.
const h1Txt = 'this is h1';
const headerP = 'this is paragraph!';
let i = 0;
let j = 0;
window.addEventListener('load', function() {
console.log('typing');
executeAsynchronously([typeWriter, typeWriter2], 100);
});
function executeAsynchronously(functions, timeout) {
for (var i = 0; i < functions.length; i++) {
setTimeout(functions[i], timeout);
}
}
// The typewriter method for h1
function typeWriter() {
if (i < h1Txt.length) {
document.getElementById('h1-text').innerHTML += h1Txt.charAt(i);
i++;
setTimeout(typeWriter, 100);
}
}
// The typewriter method for p
function typeWriter2() {
if (j < headerP.length) {
document.getElementById('p-text').innerHTML += headerP.charAt(j);
j++;
setTimeout(typeWriter2, 100);
}
}
<h1 class="text-floating" id="h1-text"></h1>
<p id="p-text"></p>
Upvotes: 2