right now I am practicing javascript and I wanted to make a typewriter effect to a text, showing character by character, then pause for 1 second and then remove one by one. I already did this part and it works for me, but I want to do a couple more things, the first is that I want to print a different word every time the previous one is deleted, these words will be predefined inside an array to iterate with them, the second is Let this be done indefinitely.
Next I show you what I have, which is to print and delete a word:
Html:
<div >
<p>NOS ENCANTA CREAR</p>
<p></p> <!-- here printwords -->
</div>
Javascript:
const contenedorParrafo = document.querySelector(`.slog-container__text`);
const parrafo = contenedorParrafo.lastElementChild;
const arrPalabras = [`SOLUCIONES`, `ARTE`, `IDEAS`]; //words with which I want to iterate
let palabra = arrPalabras[0];
const maquina = palabra =>{
let arrCaracteres = palabra.split(``);
let i = 0;
const mostrarCaracteres = setInterval(()=>{
if(i === arrCaracteres.length){
clearInterval(mostrarCaracteres);
setInterval(()=>{
let caracter;
const quitarCaracteres = setInterval(()=>{
arrCaracteres.pop();
caracter = arrCaracteres.join(``);
parrafo.innerHTML = caracter;
if(arrCaracteres.length === 0){
clearInterval(quitarCaracteres);
}
},150); //wait time to delete character
},1000); //timeout to switch from printing to deleting characters
}else{
parrafo.innerHTML = arrCaracteres[i];
i ;
}
},150); //wait time to print character
}
maquina(palabra); // here i execute
this works for me to show and delete a word, but I have tried to iterate with the others and I have not succeeded, I also want to make this function be done indefinitely
CodePudding user response:
You can do this using promises like this, make the maquina function return a promise which gets resolved whenever a word is completeley deleted, using reduce iterate over all the words and wait for each word's promise to get resolved, once its done start printing the next word. And for it to be infinite, if it's the last word in the array call the print function again.
const contenedorParrafo = document.querySelector(`.slog-container__text`);
const parrafo = contenedorParrafo.lastElementChild;
const arrPalabras = [`SOLUCIONES`, `ARTE`, `IDEAS`]; //words with which I want to iterate
var isWindowFocused = true;
const maquina = (palabra, index) =>
new Promise((res, rej) => {
let arrCaracteres = palabra.split(``);
let i = 0;
const mostrarCaracteres = setInterval(() => {
if (i === arrCaracteres.length) {
clearInterval(mostrarCaracteres);
const removeChars = setInterval(() => {
let caracter;
const quitarCaracteres = setInterval(() => {
arrCaracteres.pop();
caracter = arrCaracteres.join(``);
parrafo.innerHTML = caracter;
if (arrCaracteres.length === 0) {
clearInterval(quitarCaracteres);
clearInterval(removeChars);
// if its the last word call the print function again and start over
if (index === arrPalabras.length - 1) print();
// resolve the promise after all chars have been deleted
res("done");
}
}, 150); //wait time to delete character
}, 1000); //timeout to switch from printing to deleting characters
} else {
parrafo.innerHTML = arrCaracteres[i];
i ;
}
}, 150); //wait time to print character
})
const print = () =>
arrPalabras.reduce(async(prevPromise, palabra, index) => {
//wait for previous task to be done
await prevPromise;
// start the next task
return maquina(palabra, index)
}, Promise.resolve());
print(); // here i execute
// clear all intervals
const clearAll = () => {
const interval_id = window.setInterval(function() {}, Number.MAX_SAFE_INTEGER);
for (let i = 1; i < interval_id; i ) {
window.clearInterval(i);
}
}
// detect document visibilitychange
document.addEventListener('visibilitychange', function async() {
// clear intervals and remove text
if (document.hidden) {
console.log('left');
isWindowFocused = false
parrafo.innerHTML = ''
clearAll();
} else {
// call print and start over
console.log('back');
isWindowFocused = true;
print();
}
}, false);
<div >
<p>NOS ENCANTA CREAR</p>
<p></p>
<!-- here printwords -->
</div>