简体   繁体   English

Function 没有全局变量就不能工作?

[英]Function won't work without a global variable?

I know this is probably a very novice question but I can't seem to find the answer online anywhere and I can't see why this is happening.我知道这可能是一个非常新手的问题,但我似乎无法在任何地方在线找到答案,我不明白为什么会发生这种情况。 So, at the risk of getting downvoted... I was hoping to find an answer here.所以,冒着被否决的风险......我希望在这里找到答案。

I almost have my code to work as I want it to, but I do not want to be using any global variables.我几乎可以让我的代码按我的意愿工作,但我不想使用任何全局变量。 However, whenever I put this variable into any of my function, the code stops working..但是,每当我将此变量放入我的任何 function 时,代码就会停止工作。

I would greatly appreciate some insight.我将不胜感激。 Sorry if this question has been asked a thousand times.对不起,如果这个问题已经被问了一千次。 They way that I understand global/local binding - this shouldn't be happening?他们以我理解全局/本地绑定的方式 - 这不应该发生吗?

Here is my code with comments out wherever I tried to place the variable instead of at the top of the function.这是我的代码,无论我试图将变量放在哪里,而不是在 function 的顶部,都带有注释。

Thanks in advance.提前致谢。

<body>

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

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

One problem is一个问题是

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

An inline handler will require either the referenced function to be global (or to be inside some with scopes, which should not be used).内联处理程序将要求引用的 function 是全局的(或在某些范围内with不应使用)。 You'll need to attach the event listener with Javascript instead.您需要改为使用 Javascript 附加事件侦听器。

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

If you want letCounter to be scoped just to your script, you can put it (and everything else) inside an IIFE.如果您希望letCounter适用于您的脚本,您可以将它(以及其他所有内容)放在 IIFE 中。 That way, the scope of the letCounter is constrained to your module, and isn't global:这样, letCounter 的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>

It looks like the letCounter variable is only being used inside the typeWriter function, so you could go further and scope letCounter to only inside that function. It looks like the letCounter variable is only being used inside the typeWriter function, so you could go further and scope letCounter to only inside that function. (It's usually a good idea to constrain variable scope as much as possible, after all) (毕竟,尽可能约束变量 scope 通常是个好主意)

 (() => { 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>

Functions need a global variable for the scenario you're doing where you want to increment the value each time.函数需要一个全局变量,用于您正在执行的场景,您希望每次都增加值。

The more complicated solution to this is change an attribute called “value” in your html and read it and set it each time treating it like a global variable.更复杂的解决方案是更改 html 中名为“value”的属性,并在每次将其视为全局变量时对其进行读取和设置。

You can add the letCounter into the DOM like this您可以像这样将 letCounter 添加到 DOM 中

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

I dislike the use of onclick="" method calls so i prefer the use of on eventListener.我不喜欢使用 onclick="" 方法调用,所以我更喜欢使用 on eventListener。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM