【问题标题】:Weirdest repeat call of function ever有史以来最奇怪的重复调用函数
【发布时间】:2013-12-02 18:50:34
【问题描述】:

我制作了一个验证有问题的调查表。有几个验证函数,在单击提交按钮时调用。但是第一个验证函数会被调用两次。为了显示这个问题,我制作了一个有同样问题的简单版本。这是整个源代码:

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo Double Call</title>
</head>
<body>
<form name="upssForm" action="submit.php" method="POST" onsubmit="return validateForm()">
    A1 <input type="radio" name="A" value="1">
    A2 <input type="radio" name="A" value="2"><br>
    B1 <input type="radio" name="B" value="1">
    B2 <input type="radio" name="B" value="2"><br>
    <button type="button" onclick="validateForm()">Validate and submit button</button><br>
    <input type="submit" value="Validate and submit input">
</form>
<script>
function checkA() {
    var radioA = upssForm.elements['A'];
    if (radioA[0].checked == false) {
        alert('A1 not checked');
        return false;
    }
    else return true;
}

function checkB() {
    var radioB = upssForm.elements['B'];
    if (radioB[0].checked == false) {
        alert('B1 not checked');
        return false;
    }
    else return true;
}

function validateForm() {
    checkA();
    checkB();
    if ((checkA() == false) || (checkB() == false))
        return false;
    else
        upssForm.submit();
        // return true; /* doesn't work either with the submit input */
}
</script>
</body>
</html>

只需单击提交按钮或提交输入,就会看到警报“A1 未检查”出现两次,这是在函数 checkB() 执行后的第二次。是什么原因造成的,我该如何解决?

【问题讨论】:

    标签: javascript function validation


    【解决方案1】:

    您调用了两次checkA(),一次在validateForm() 的开头,一次在if() 语句中。

    将结果存储在变量中,然后在if() 语句中检查:

    var aResult = checkA();
    if(aResult == false) {
    }
    

    【讨论】:

      【解决方案2】:

      WildCrustacean 给出的答案确实解决了这个问题。为了记录和将来参考,我将给出整个函数应该如何:

      function validateForm() {
          var aResult = checkA();
          var bResult = checkB();
          if ((aResult == false) || (bResult == false))
              return false;
          else
              upssForm.submit();
      }
      

      谢谢大哥!

      【讨论】:

        【解决方案3】:

        WildCrustacean 的答案是正确的,所以我已经编辑了我的答案。仅供参考,您可能想要重构您的 if 语句。例如,if (foo == false)if (!foo) 相同(尽管有趣的是,if (foo === false) 不是)。因此,结合 WildCrustacean 的答案并取出一些冗余代码:

        function checkA() {
            var radioA = upssForm.elements['A'];
            if (!radioA[0].checked) {
                alert('A1 not checked');
            }
            return radioA[0].checked;
        }
        
        //function checkB() { ...
        
        function validateForm() {
            var a = checkA();
            var b = checkB();
            if (a && b) {
                upssForm.submit();
            } 
            return false;
        }
        

        validateForm 总是返回 false 没关系,因为唯一会影响任何事情的是用户在表单无效时单击输入(而不是按钮)。

        演示:http://jsfiddle.net/5GA5F/2/

        事实上,如果您不介意看起来很奇怪的代码,您可以利用布尔短路来进一步缩小代码:

        function checkA() {
            var radioA = upssForm.elements['A'];
            return radioA[0].checked || alert('A1 not checked');
        }
        
        function checkB() {
            var radioB = upssForm.elements['B'];
            return radioB[0].checked || alert('B1 not checked');
        }
        
        function validateForm() {
            var a = checkA(),
                b = checkB();
            return a && b && upssForm.submit();
        }
        

        演示:http://jsfiddle.net/5GA5F/3/

        【讨论】:

        • +1:这解决了当前代码中需要解决的许多问题。
        • 没有return true,表单也被提交,Firebug没有任何错误报告。关于代码的“剪裁”:非常感谢。
        • @FrankConijn - 有趣的是,当我尝试它时它没有提交。我将编辑该部分,直到我确定它是正确的。无论哪种方式,很高兴我能提供帮助。
        【解决方案4】:

        这是另一种方法:

        function validateForm() {
            if ((result = (checkA() && checkB()))){
                upssForm.submit();
            }
        
            return result;
        }
        

        这样,您的函数总是 返回有关它是否成功的信息。这里要注意的另一件事:在 JavaScript 中,赋值语句返回赋值的值。我们不必单独分配结果值,因为我们可以在 if 条件中调用它。

        要记住一件事:checkB() 只有在checkA() 成功时才会运行。如果您需要它们都执行,请将它们的值分配给一个变量,然后检查这些变量。

        【讨论】:

          猜你喜欢
          • 2021-11-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多