最奇怪的重复函数调用

时间:2013-12-02 18:50:35

标签: javascript function validation

我制作了一份问卷表,其中包含验证问题。有几个验证函数,单击提交按钮时会调用这些函数。但是第一个验证函数然后被调用两次。为了显示问题,我制作了一个具有相同问题的裸骨版本。这是完整的源代码:

<!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()后。造成这种情况的原因是什么,我该如何解决?

4 个答案:

答案 0 :(得分:3)

您拨打checkA()两次,一次在validateForm()的开头,一次在if()语句中。

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

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

答案 1 :(得分:1)

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

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

谢谢,兄弟!

答案 2 :(得分:1)

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/

答案 3 :(得分:0)

这是另一种方法:

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

    return result;
}

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

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