2013-12-02 4 views
1

Я создал анкету, которая имеет проблемы с проверкой. Существует несколько проверяющих функций, вызываемых при нажатии кнопки отправки. Но первая проверяющая функция затем вызывается дважды. Чтобы показать проблему, я сделал версию с голыми костями, которая имеет ту же проблему. Это весь исходный код:Самый странный повторный вызов функции когда-либо

<!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() выполняется. Что вызывает это и как его решить?

ответ

3

Вы звоните checkA() дважды, один раз в начале validateForm() и один раз в заявлении if().

магазин результат в переменной, а затем проверить, что в if() заявлении:

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

Спасибо, это действительно трюк! –

1

Ответ WildCrustacean дал действительно решить эту проблему. Для записи и будущих справок я просто дам всю функцию, как она должна быть:

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

Спасибо, брат!

0

Вот еще один способ сделать это:

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

    return result; 
} 

Таким образом, ваша функция всегда возвращает информацию о преуспевает ли он или нет. Еще одно замечание: JavaScript в операторах присваивания возвращает значение присваивания. Нам не нужно было назначать значение результата отдельно, потому что мы могли бы назвать его в состоянии if.

Следует иметь в виду: checkB() будет работать только в том случае, если checkA() преуспевает. Если вам нужно их выполнить, назначьте их значения переменной, а затем проверьте эти переменные.

1

Ответы WildCrustacean верны, поэтому я отредактировал мой. Просто FYI, вы можете захотеть реорганизовать свои 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(); 
} 

Demo: http://jsfiddle.net/5GA5F/3/

+0

+1: это касается многих вещей, которые необходимо решить в текущем коде. – ramblinjan

+0

Без 'return true', форма также отправляется без отчета об ошибке Firebug.Что касается «пошива» кода: это ценится. –

+0

@FrankConijn - Интересно, он не отправил, когда я попробовал. Я собираюсь отредактировать эту часть, пока не буду уверен, что это правильно. В любом случае, я рад, что смогу помочь. –

Смежные вопросы