简体   繁体   中英

Function not triggering even though it's called

I'm writing a website, and part of it requires some text to appear as if it's being typed. However, one of my functions to do this ( typewriter2 ) isn't working, even though it's called.

I've tried moving around the code, and testing it separately. The code runs fine, however the typewriter2 function just won't start.

 var x = document.getElementById("businesscard"); if (x.style.display === "none") { x.style.display = "block"; } else { x.style.display = "none"; } var i = 0; var txt1 = "cd Info && cat Business Card"; var speed = 75; function typeWriter() { if (i < txt1.length) { document.getElementById("cmd1").innerHTML += txt1.charAt(i); i++; setTimeout(typeWriter, speed); } else { BusinessCard(); } } function BusinessCard() { var x = document.getElementById("businesscard"); if (x.style.display === "none") { x.style.display = "block"; typeWriter2(); } else { x.style.display = "none"; } } var txt = "cat Websites"; function typeWriter2() { if (i < txt.length) { document.getElementById("cmd2").innerHTML += txt.charAt(i); i++; setTimeout(typeWriter2, speed); } } 
 /* unvisited link */ a:link { color: white; } /* visited link */ a:visited { color: white; } /* mouse over link */ a:hover { color: blue; } /* selected link */ a:active { color: blue; } body { background-color: #300A24; color: white; font-family: 'Ubuntu Mono', monospace; } 
 <body onload="typeWriter()"> <link href="https://fonts.googleapis.com/css?family=Ubuntu+Mono&display=swap" rel="stylesheet"> <p id="cmd1">[dmeskin@code-u.org ~]$ </p> <div id="businesscard"><p>Daniel Notmylastname<br> Student at notmyschoool<br> Systems Administrator<br> <a href="http://code-u.org">http://code-u.org</a><br> <a href="mailto:1byte@gmail.com">1byte@gmail.com</a><br> <a href="tel:9175556761">+1(917)-555-6761</a><br><p id="cmd2">[dmeskin@code-u.org Info]$ </p> 

What's supposed to be happening is that typeWriter2() starts after businesscard is unhidden, but it doesn't.

Using global variables will hurt you. It makes the code unpredictable, especially if you use the same variable in more than one function.

Another thing: Don't query the DOM for the element every time you need the element: Querying the DOM is expensive and should be avoided if possible (in your code it dosen't matter, but since th fix is so easy, I would like you to learn doing the right thing from the start.) In your code it is the same element that it was 75 milliseconds ago.

Yet another thing: Don't repeat yourself. If you write the same piece of code over and over in the same program, or with just another variable, it is time to move that to a function. Then you have ONE place too look at when you are troubleshooting, and ONE place to apply a fix if needed.

The example below is NOT perfect by any means. A modern variant would probably use arrow-functions , but I decided against that in this example, since they can be hard to read if you aren't used to it.

Here is a little improved version that reuses the same function for the typewriter effect.

 // A function that hides and show the Business card depending on the given variable. function setBusinessCardVisible (visibility) { const elem = document.getElementById("businesscard"); elem.style.display = visibility ? 'block' : 'none'; } // A generig typewriter that takes an object and callback as arguments. // The arg object has: // elem : the element that text shold be appended to // cmd : The text that should be added // delay : the delay between characters function typeWriter (arg, callback) { let index = 0; // set the index for this typewriter to 0. // Get the elment ONE time, and resuse that. arg.elem.textContent = arg.prompt; const length = arg.cmd.length; // Using setInteval to start ONE timer that will be called // until it is cleared with clearInterval let timer = setInterval( function () { // Add the character arg.elem.textContent += arg.cmd.charAt(index); // increment index and see if we are finished if (index++ >= length) { clearInterval(timer); // stop the timer if (callback) callback(); // call callback if specified } }, arg.delay ); } // call this function to start the effect function startTyping () { const elem1 = document.getElementById('cmd1'), elem2 = document.getElementById('cmd2'), delay = 75, // Set the delay here and reuse it below cmdprompt1 = "[dmeskin@code-u.org ~]$ ", // Part one: hide the card. cmdprompt2 = "[dmeskin@code-u.org Info]$ "; elem1.textContent = cmdprompt1; elem2.textContent = cmdprompt2; // Part one: hide the card. setBusinessCardVisible(false); // Start the first typewriter typeWriter({ elem: elem1, prompt: cmdprompt1, cmd: "cd Info && cat Business Card", delay: delay }, function () { // part two, show the card setBusinessCardVisible(true); // Start the secord typewriter setTimeout( function() { typeWriter({ elem: elem2, prompt: cmdprompt2, cmd: "cat Websites", delay: delay }, function () { setTimeout(function () { setBusinessCardVisible(false); elem1.textContent = cmdprompt1; elem2.textContent = cmdprompt2; setTimeout(startTyping, 2000); // Restart after 2 seconds }, 2000); }) }, 2000) // delay after showing card }); } 
 a, a:link, a:visited, a:hover, a:active { color: blue; } body { background-color: #300A24; color: white; font-family: monospace; } 
 <body onload="startTyping()"> <p id="cmd1">[dmeskin@code-u.org ~]$ </p> <div id="businesscard"> <p>Daniel Notmylastname<br> Student at notmyschoool<br> Systems Administrator<br> <a href="http://code-u.org">http://code-u.org</a><br> <a href="mailto:1byte@gmail.com">1byte@gmail.com</a><br> <a href="tel:9175556761">+1(917)-555-6761</a><br> <p id="cmd2">[dmeskin@code-u.org Info]$ </p> </div> </body> 

问题是i未设置为正确的值,因此必须重命名。

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