首页 > 解决方案 > 如果没有全局变量,函数将无法工作?

问题描述

我知道这可能是一个非常新手的问题,但我似乎无法在任何地方在线找到答案,我不明白为什么会发生这种情况。所以,冒着被否决的风险......我希望在这里找到答案。

我几乎可以让我的代码按我的意愿工作,但我不想使用任何全局变量。但是,每当我将此变量放入我的任何函数中时,代码都会停止工作..

我将不胜感激。对不起,如果这个问题已经被问了一千次。他们以我理解全局/本地绑定的方式 - 这不应该发生吗?

这是我的代码,无论我试图将变量放在哪里而不是在函数的顶部,都带有注释。

提前致谢。

<body>

    <div class="style" onclick="typeWriter()">
      <p id="remove">Hide Me</p>
      <p id="type"></p>
  </div>
</body>

//Javascript

  let letCounter = 0; //Do not want this as a global variable


  function hideInitText() {
    let hide = document.getElementById("remove");
    hide.classList.add("hide");
    //let letCounter = 0; //I tried here
  }
  hideInitText();

  function typeWriter() {
    //let letCounter = 0; //I tried here

    let cycle, classCounter; //establish the cycle and counter
    cycle = document.querySelectorAll("#type"); //cycle includes the .type class
    for (classCounter = 0; classCounter < cycle.length; classCounter++) { //for loop that actually cycles
      //let letCounter = 0; //I tried here
      typeOut();
    }

    function typeOut() {
      //let letCounter = 0; //I tried here
      let speed = 50; //speed in milliseconds
      let typewriter = "Type me out"; //document.querySelectorAll(".type");
      if (letCounter < typewriter.length) {
        //let letCounter = 0; //I tried here
        //hide.classList.remove("hide"); //unhide the text
        cycle[classCounter].innerHTML += typewriter.charAt(letCounter);
        letCounter++;
        setTimeout(typeWriter, speed);
      }
    }
  };

标签: javascriptdom

解决方案


一个问题是

<div class="style" onclick="typeWriter()">

内联处理程序将要求引用的函数是全局的(或在某些with范围内,不应使用)。您需要改为使用 Javascript 附加事件侦听器。

document.querySelector('div').addEventListener('click', typeWriter);

如果您只想letCounter范围限定为您的脚本,您可以将它(以及其他所有内容)放在 IIFE 中。这样, 的范围被限制在您的模块中,并且不是全局的:letCounter

(() => {
  let letCounter = 0;


  function hideInitText() {
    let hide = document.getElementById("remove");
    hide.classList.add("hide");
  }
  hideInitText();

  function typeWriter() {
    let cycle, classCounter; //establish the cycle and counter
    cycle = document.querySelectorAll("#type"); //cycle includes the .type class
    for (classCounter = 0; classCounter < cycle.length; classCounter++) { //for loop that actually cycles
      typeOut();
    }

    function typeOut() {
      let speed = 50; //speed in milliseconds
      let typewriter = "Type me out"; //document.querySelectorAll(".type");
      if (letCounter < typewriter.length) {
        //hide.classList.remove("hide"); //unhide the text
        cycle[classCounter].innerHTML += typewriter.charAt(letCounter);
        letCounter++;
        setTimeout(typeWriter, speed);
      }
    }
  }
  document.querySelector('div').addEventListener('click', typeWriter);
})();
<div class="style">
  <p id="remove">Hide Me</p>
  <p id="type"></p>
</div>

看起来该letCounter变量仅在typeWriter函数内部使用,因此您可以更进一步并将范围letCounter仅限于该函数内部。(毕竟,尽可能地限制变量范围通常是个好主意)

(() => {
  function hideInitText() {
    let hide = document.getElementById("remove");
    hide.classList.add("hide");
  }
  hideInitText();

  const typeWriter = (() => {
    let letCounter = 0;
    return () => {
      let cycle, classCounter; //establish the cycle and counter
      cycle = document.querySelectorAll("#type"); //cycle includes the .type class
      for (classCounter = 0; classCounter < cycle.length; classCounter++) { //for loop that actually cycles
        typeOut();
      }

      function typeOut() {
        let speed = 50; //speed in milliseconds
        let typewriter = "Type me out"; //document.querySelectorAll(".type");
        if (letCounter < typewriter.length) {
          //hide.classList.remove("hide"); //unhide the text
          cycle[classCounter].innerHTML += typewriter.charAt(letCounter);
          letCounter++;
          setTimeout(typeWriter, speed);
        }
      }
    };
  })();
  document.querySelector('div').addEventListener('click', typeWriter);
})();
<div class="style">
  <p id="remove">Hide Me</p>
  <p id="type"></p>
</div>


推荐阅读