有史以来最奇怪的函数重复调用

Weirdest repeat call of function ever

本文关键字:调用 函数 有史以来      更新时间:2024-01-20

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

<!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()之后。是什么导致了这种情况,我该如何解决?

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

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

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

野生甲壳纲给出的答案确实解决了这个问题。为了记录和将来的参考,我只给出它应该是什么样的整个功能:

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

谢谢,兄弟!

野生甲壳动物的答案是正确的,所以我把我的答案编辑下来了。仅供参考,您可能需要重构if语句。例如,if (foo == false)if (!foo)相同(尽管有趣的是,if (foo === false)不是)。所以,结合野生甲壳动物的答案,去掉一些多余的代码:

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/

这里有另一种方法:

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

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

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