没有全局变量,函数将无法工作?

时间:2019-11-20 04:06:15

标签: javascript dom

我知道这可能是一个非常新手的问题,但是我似乎无法在任何地方在线找到答案,也无法理解为什么会这样。因此,冒着被低估的风险...我希望在这里找到答案。

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

我将不胜感激。抱歉,这个问题被问了一千遍了。他们以这种方式了解全局/本地绑定-这不应该发生吗?

这是我的代码,其中有注释,无论我在何处放置变量,而不是在函数顶部。

先谢谢了。

<body>

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

// Java

  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);
      }
    }
  };

3 个答案:

答案 0 :(得分:2)

一个问题是

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

答案 1 :(得分:1)

在您每次要增加值的情况下,函数都需要一个全局变量。

对此更复杂的解决方案是在html中更改一个称为“值”的属性,并在每次将其视为全局变量时对其进行读取和设置。

答案 2 :(得分:1)

您可以像这样将letCounter添加到DOM中

const element = document.getElementById('counter');
let letCounter = element.dataset.count;
<div id="counter" data-count="0"></div>

我不喜欢使用onclick =“”方法调用,因此我更喜欢使用on eventListener。