【问题标题】:main loop function doesn't run nested functions主循环函数不运行嵌套函数
【发布时间】:2018-09-02 16:40:47
【问题描述】:

我是 JavaScript 和编程领域的新手,我正在努力进行基本的 JavaScript 练习,我应该只使用基本函数创建一个基于用户提示值的时间表,它应该是一个循环,当用户插入值-1。 虽然,在我用 -1 中断循环之前,循环不会打印时间表,但它似乎循环得太快了。

这是我的代码:

var userInput;

function checkValidity(question) {

  if(isNaN(question) || (question === "" )) {
    console.log('Inserire un numero valido');
    return false;
  } else {
    console.log('defined');
    return true;
  }
}

function timeTable(valueUser) {
  document.write("Times Table for number: " + valueUser + "<br />");
  
  for(var i = 0; i < 10; i++) {					
    document.write(valueUser + " * " + i + " = " + valueUser * i + "<br />");
  }

}

function showQuestion() {
  userInput = parseInt(prompt("Enter your Times Table value:"));
  
  var answerValidate = checkValidity(userInput);

  if(answerValidate) {
    if(userInput !== -1) {
      timeTable(userInput);
      showQuestion();
    } else {
      console.log("Grazie per aver partecipato!");
    }
  } else {
    showQuestion();
  }

  
}

showQuestion();

任何人都可以建议我做错了什么?

谢谢大家!

【问题讨论】:

  • 请正确格式化您的代码,尤其是:删除大量意图
  • 到目前为止,循环仅将传递给 timeTable 的值打印十次,然后返回给调用者。应该在调用函数中设置循环(我建议在这里使用while 循环,并且您还希望避免递归。

标签: javascript function loops if-statement


【解决方案1】:

document.write 不会立即完成它的工作,它只是将工作放在队列中,而“浏览器”将在它无事可做时完成该工作。通过在调用document.write 之后直接调用showQuestion,您可以保持“浏览器”被占用。因此,一旦递归停止(当用户输入-1),它将执行那些累积的工作。

要解决此问题,只需将下一次调用 showQuestion 并使用 setTimeout 立即排队(或延迟 0):

setTimeout(showQuestion);

示例:

var userInput;

function checkValidity(question) {

  if(isNaN(question) || (question === "" )) {
    console.log('Inserire un numero valido');
    return false;
  } else {
    console.log('defined');
    return true;
  }
}

function timeTable(valueUser) {
  document.write("Times Table for number: " + valueUser + "<br />");
  
  for(var i = 0; i < 10; i++) {					
    document.write(valueUser + " * " + i + " = " + valueUser * i + "<br />");
  }

}

function showQuestion() {
  userInput = parseInt(prompt("Enter your Times Table value:"));
  
  var answerValidate = checkValidity(userInput);

  if(answerValidate) {
    if(userInput !== -1) {
      timeTable(userInput);
      setTimeout(showQuestion);
    } else {
      console.log("Grazie per aver partecipato!");
    }
  } else {
    showQuestion();
  }
}

showQuestion();

话虽如此,我建议您根本不要使用document.write,使用console.log 之类的替代方法或更改特定元素的textContent。此外,使用&lt;input&gt; 元素代替侵入性的prompt 调用。这里不需要循环,用户可以输入任意数量的值。

示例:

function timesTable(valueUser) {
  var result = "Times Table for number: " + valueUser + "\n";          // accumulate the result in a string (use "\n" instead of "<br>")
  
  for(var i = 0; i < 10; i++) {					
    result += valueUser + " * " + i + " = " + valueUser * i + "\n";
  }
   
  return result;                                                       // and return it
}

function showQuestion() {
  var value = parseInt(document.getElementById("my-input").value);     // get the value from the input
  
  if(isNaN(value)) {                                                   // if it is not valid
    alert("Invalid input! Try again!");                                // alert the user and urge him to start over
  } else {                                                             // otherwise
    document.getElementById("my-result").textContent = timesTable(value); // create the times table of this number and show them in the my-result element 
  }
}

document.getElementById("my-button").onclick = function() {            // when the button is clicked
    showQuestion();                                                    // call showQuestion
};
<input id="my-input"><button id="my-button">Show times table</button>
<pre id="my-result"></pre>

【讨论】:

    【解决方案2】:

    我认为这段代码运行良好。您缺少的是 prompt() 被阻塞并且在此函数返回之前无法运行任何 JavaScript。

    为避免这种情况,不要使用prompt(),而是使用简单的&lt;input type="text" /&gt;。显然,这会将您从正在使用的同步范例中踢出来,并需要以异步方式重组您的代码。这很容易做到,真的。这应该可以帮助您:

    <input id="campo_di_testo" type="text" /><input id="bottone_invia" type="button" value="invia" />
    
    <script>
    
      document.getElementById("bottone_invia").onclick = () => {
        var textNode;
    
        textNode = document.getElementById("campo_di_testo");
        console.log("hai premuto invia e il testo immesso è: " + textNode.value);
      };
    
    </script>
    

    另外避免使用document.write(),正如易卜拉欣指出的那样。它将覆盖 DOM 树并删除 &lt;input&gt; 元素。

    您可以像这样使用&lt;textarea&gt;

    <textarea id="area"></textarea>
    
    // in JS:
    var area = document.getElementById("area");
    area.value += "nuova riga da appendere" + "\n";
                                              ^^^^ don't forget to append the newline
    

    或者,类似地,任何&lt;div&gt; 像这样:

    <div id="output"></div>
    
    // in JS:
    var output = document.getElementById("output");
    output.innerText += "nuova riga da appendere" + "<br />";
    

    【讨论】:

      猜你喜欢
      • 2014-04-24
      • 1970-01-01
      • 2018-08-20
      • 1970-01-01
      • 1970-01-01
      • 2011-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多