javascript - 即使调用了函数也不会触发
问题描述
我正在写一个网站,其中一部分需要一些文本才能显示出来,就好像它正在被输入一样。但是,我执行此操作的函数之一 ( typewriter2
) 不起作用,即使它被调用。
我试过移动代码,并单独测试它。代码运行良好,但typewriter2
功能无法启动。
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>
应该发生的事情是在未隐藏typeWriter2()
之后开始businesscard
,但事实并非如此。
解决方案
使用全局变量会伤害你。它使代码不可预测,特别是如果您在多个函数中使用相同的变量。
另一件事:不要在每次需要元素时查询 DOM 的元素:查询 DOM 很昂贵,如果可能的话应该避免(在你的代码中它并不重要,但由于修复很容易,我会就像你从一开始就学习做正确的事情。)在你的代码中,它与 75 毫秒前的元素相同。
还有一件事:不要重复自己。如果您在同一个程序中一遍又一遍地编写相同的代码,或者只使用另一个变量,那么是时候将其移动到函数中了。然后,当您进行故障排除时,您也可以在一个地方查看,如果需要,可以在一个地方应用修复。
下面的例子无论如何都不是完美的。现代变体可能会使用箭头函数,但我在这个例子中决定反对,因为如果你不习惯它们可能很难阅读。
这是一个稍微改进的版本,它为打字机效果重用了相同的功能。
// 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>
推荐阅读
- arrays - 返回具有固定形状的列和行的数组列表的每个元素的平均数组
- python - 这是解决BST问题的正确方法吗?
- python - 当我在我的在线服务器上运行一个函数时,我收到了一个错误(502 bad gateway)。在我的本地服务器上运行时我没有得到同样的错误
- couchbase - N1QL 选择数字键
- twitter - Flink Twitter 连接器 - 如何避免超出速率限制 (420)
- javascript - amp-form post action-xhr 响应剥离图像标签
- python - 用于银行交易分类的 TensorFlow 实现
- java - 使用外部控制输入来选择类或代码(“不安全反射”)
- python - 将“on_start 数据”传递给 MyScreen 和 MyImage 需要 ScreenManager 中的屏幕名称
- json - 将 JSON 节点转换为要选择的列