javascript - 函数即使被调用也不会触发

标签 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 毫秒前的元素相同。

还有一件事:不要重复你自己。如果您在同一个程序中一遍又一遍地编写相同的代码,或者只是使用另一个变量,那么是时候将它移到一个函数中了。这样一来,您在进行故障排除时就可以在一个地方查看,并在需要时在一个地方应用修复。

下面的例子无论如何都不完美。现代变体可能会使用 arrow-functions ,但在这个示例中我决定不这样做,因为如果您不习惯,它们可能很难阅读。

这里是一个稍微改进的版本,它为打字机效果重用了相同的函数。

// 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>

关于javascript - 函数即使被调用也不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57642115/

相关文章:

javascript - jQuery在模式框中向服务器发出多个请求

javascript - React Native/node 问题 : The package was successfully found. 但是,该包指定了无法解析的 `main` 模块字段

javascript - 修复脚本仅更新一条记录

javascript - 如何制作一直运行的脚本?

JavaScript onclick 事件在 IE9 及更低版本中不起作用

javascript - 使用 Node 将 JPG 文件转换为 MP4 视频

javascript - React Router VS 条件渲染

javascript - 如何从子网格功能区 Xml 中引用 JavaScript 库

javascript - 如何从具有多个元素和类的 div 容器中删除一个 css 类?

javascript - 从基于 session 的 token 机制转向 OAuth 2.0 机制