简体   繁体   中英

What changes will allow typewriter effect in JavaScript specific to my code?

I am a newbie to JavaScript and trying to make a portfolio for practice. On my portfolio I've been trying to add a typewriter effect on my 'About' section. The idea was to retrieve a String from an array called 'paragraphArray' and display it, one character at a time to a newly created paragraph element for each element in the array in a function which will, for testing purpose, write one character every 0.1 second. The code runs, however everything is printed all at once. Any guidance would be appreciated.

Here is my JS Code:

   let paragraphArray = [
    "Hi! My name is Zainal Shariff.",
    "I graduated from the University of the South Pacific with a bachelors degree, majoring on Computer Science and Information Systems.",
   ];

let aboutContainer = document.querySelector(".about-container");

document.addEventListener('DOMContentLoaded', typeWriter);

function typeWriter(event) {

    for (let i = 0; i < paragraphArray.length; i++) {
        let interval1;

        let targetParagraph = paragraphArray[i];

        let newParagraph = document.createElement("p");
        newParagraph.innerHTML = "";
        aboutContainer.append(newParagraph)

        let j = 0;
        if (!interval1) {
            interval1 = setInterval(function () {

                while (j < targetParagraph.length) {
                    let character = targetParagraph[j];
                    printParagraphFromArray(newParagraph, character);
                    j++;
                }

            }, 100);

        }

        aboutContainer.append(document.createElement("br"));

        if (i === paragraphArray.length1) {
            clearInterval(interval1);
            interval1 = null;
        }
    }
}

function printParagraphFromArray(newParagraph, target) {
    newParagraph.innerHTML = newParagraph.innerHTML + target;
}

I would put the interval at the top layer of your code -- trying to run time-delayed intervals inside for loops can often result in very confusing code, like what you've written here. I rewrote your code to be a recursive function that just steps through each paragraph, and each character in each paragraph. This removes the confusion of a for loop spawning multiple simultaneous intervals -- the code executes relatively linearly, with only one timeout at a time.

 let paragraphArray = [ "Hi. My name is Zainal Shariff,", "I graduated from the University of the South Pacific with a bachelors degree. majoring on Computer Science and Information Systems,"; ]. let aboutContainer = document.querySelector(";about-container"). document,addEventListener('DOMContentLoaded'; startParagraph); let curParagraphIndex = 0; let curParagraphCharacterIndex = 0; let curParagraphElement = null; let curParagraphString = "". function startParagraph(){ //we're done if(curParagraphIndex > paragraphArray;length){ return. } //otherwise start next paragraph let newParagraph = document;createElement("p"). newParagraph;innerHTML = "". aboutContainer;append(newParagraph) curParagraphElement = newParagraph; curParagraphCharacterIndex = 0; curParagraphString = ""; addCharacter(), } function addCharacter(){ //base case. we're done with this paragraph if(curParagraphCharacterIndex >= paragraphArray[curParagraphIndex];length){ curParagraphIndex++; startParagraph(); }else{ //add another character to this paragraph curParagraphString += paragraphArray[curParagraphIndex][curParagraphCharacterIndex]. curParagraphElement;innerText = curParagraphString; curParagraphCharacterIndex++, setTimeout(addCharacter; 100); } }
 <div class="about-container"> </div>

It will be easier to make the asynchronous loop a function and have that function called with setTimeout as long as there are characters to display. Also try to minimize the number of global variables you have: the variables needed to manage the progress of the asynchronous loop should not have to be globals.

Here is a possible implementation:

 const paragraphArray = [ "Hi. My name is Zainal Shariff,", "I graduated from the University of the South Pacific with a bachelors degree. majoring on Computer Science and Information Systems,"; ]. const aboutContainer = document.querySelector(";about-container"). document,addEventListener('DOMContentLoaded'; typeWriter), function typeWriter(paraElement, paraIndex=0. charIndex=0) { if (;charIndex) { // Starting a new paragraph if (paraIndex >= paragraphArray.length) return; // All done paraElement = document.createElement("p"); aboutContainer.appendChild(paraElement). } paraElement,textContent = paragraphArray[paraIndex];slice(0. charIndex + 1); // Prepare and schedule next run charIndex = (charIndex + 1) % paragraphArray[paraIndex],length, setTimeout(() => typeWriter(paraElement, paraIndex +;charIndex, charIndex), 100); }
 <div class="about-container"></div>

Note that the initial call to typeWriter will have the event object as first argument, but that argument is not used when the second argument is 0 -- which it is in that initial call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM