【问题标题】:Javascript stop form submittionJavascript停止表单提交
【发布时间】:2011-05-14 10:32:23
【问题描述】:

我正在为提交按钮使用这个事件监听器:

document.forms[formID].addEventListener('submit',validate);

我想让页面在提交时保持原样而不刷新或重定向, 这是validate 函数,return false; 不起作用

function validate() {

    CheckedN = this.name;
    CorrectAnswer = questions.correctAns[CheckedN];
    UserAnswer = -1;

    for (var i=0; i < 4; i++) {
        if (this.answerN[i].checked === true) {
            UserAnswer = i;
        }
    }

    if (UserAnswer === -1) {alert("Please choose an answer");}
    else {
        if (UserAnswer === CorrectAnswer) {alert("You are correct!");}
        else {alert("You are wrong!");}
        }

return false;
}

我做错了什么? 谢谢

【问题讨论】:

  • 验证函数总是返回 false 你需要在你的有效情况下返回 true
  • 既然你说你正在使用 jQuery(即使你没有在引用的代码中使用它),我已经添加了 jquery 标签让人们知道 jQuery - 具体的答案是可以的。

标签: javascript jquery forms form-submit


【解决方案1】:

编辑:您在其他地方的评论中说过您正在使用 jQuery。这很令人惊讶,因为您的代码没有使用它来连接事件处理程序。

如果您使用 jQuery,这会变得简单得多(正如我在下面的“离题”部分中提到的那样)。

这样连接起来:

$(document.forms[formID]).submit(validate);

并更改您的validate 函数以接受event 参数并在其上调用preventDefault

function validate(event) {
    event.preventDefault();
    // ...rest of function here
}

jQuery 解决了下面列出的所有问题。


原答案

有些事情要改变(但另请参阅最后的题外话):

  1. 您的addEventListener 调用缺少参数,应该是:

    document.forms[formID].addEventListener('submit',validate,false);
    //                                                        ^--- required
    
  2. 您的validate 函数将接收event 对象(在符合标准的浏览器上)。它应该有一个preventDefault 函数,当调用它时会停止浏览器的默认操作(提交表单)。因此,声明参数并在其上调用函数(如果存在)。

  3. 遗憾的是,要支持 IE,您必须使用 attachEvent 而不是 addEventListener(他们只在 IE9 中开始支持)。

  4. 同样可悲的是,要支持 IE,您必须处理这样一个事实,即它们将事件对象视为全局对象而不是将其传入。

  5. AND上面可能没有preventDefault 函数。 叹息

总而言之,连接:

var form = document.forms[formID];
if (form.addEventListener) {
    // Standards
    form.addEventListener('submit',validate,false);
}
else if (form.attachEvent) {
    // IE
    form.attachEvent('onsubmit', validate); // No third parameter, note the "on"
}
else {
    // REALLY old browser
    form.onsubmit = validate;
}

然后是函数:

function validate(event) {
    var valid;

    event = event || window.event; // Handle IE difference

    CheckedN = this.name;
    CorrectAnswer = questions.correctAns[CheckedN];
    UserAnswer = -1;

    for (var i=0; i < 4; i++) {
        if (this.answerN[i].checked === true) {
            UserAnswer = i;
        }
    }

    if (UserAnswer === -1) {
        alert("Please choose an answer");
    }
    else {
        if (UserAnswer === CorrectAnswer) {
            alert("You are correct!");
        }
        else {
            alert("You are wrong!");
        }
    }

    // Both preventDefault and return false, to cover various browser
    if (event.preventDefault) {
        event.preventDefault();
    }
    return false;
}

题外话:如您所见,您必须处理很多浏览器不一致的问题。我建议不要自己动手,而是使用像 jQueryPrototypeYUIClosureany of several others 这样的库来为您消除这些不一致(并提供许多其他方便的实用工具) ) 这样您就可以专注于您实际尝试做的事情,而不会为这些小事而烦恼。

【讨论】:

  • 感谢详细解释,我想我要改用jquery了。
  • @IlyaD:这是一个很棒的图书馆。 :-)
【解决方案2】:

这不是我的想法,但我认为提交表单的 html 控件应该是这样的:

<input type="submit" value="submit this form" onclick="return validate()"/>

【讨论】:

  • 当您可以在表单的提交时进行验证时,切勿单击提交按钮进行验证
【解决方案3】:
document.getElementById(formId).onsubmit = validate;

或者更简单,在你的页面标记中,做:

<form id="myFormId" onsubmit="return validate();">
    <!-- Form content here -->
</form>

【讨论】:

  • 不,让我们不要回到 1996 年。
  • @T.J.克劳德 - 嗯。我们回到适用于所有主要浏览器的最简单的解决方案。通过从其onSubmit() 函数返回false 来防止表单的默认行为已经存在了很长时间,有效,并且比您提供的答案要简单得多。
  • 它还将代码紧密耦合,并且(在您的第二个建议的情况下)混合代码和标记。在别人的车库里没问题;在一个拥有专门设计师和专门编码人员的大型组织中,情况并非如此。这是不必要的和限制性的。
  • 哦,让我们尝试让 addeventlistener 和 attachevent 跨浏览器工作,而 Aroth 发布的内容在我见过和使用过的所有浏览器中都可以使用。我唯一要改变的是将它添加到 window.onload 并使用 document.forms[0].onsubmit=validate;这叫务实。
【解决方案4】:

这适用于所有使用纯 JS 的浏览器。让投票盛宴开始

http://jsfiddle.net/mplungjan/zUFEw/

window.onload=function() {
  document.forms[0].onsubmit=validate; 
}

function validate() {
  var CheckedN = this.name;
  var CorrectAnswer = questions.correctAns[CheckedN];
  var UserAnswer = -1;
  for (var i=0, n=this.answerN.length; i < n; i++) {
    if (this.answerN[i].checked) {
      UserAnswer = i;
      break; // assuming only one answer
    }
  }

  if (UserAnswer === -1) {alert("Please choose an answer");}
  else {
    if (UserAnswer === CorrectAnswer) {alert("You are correct!");}
    else {alert("You are wrong!");}
  }
  return false; // will always stop submission unless there is an error above
}

PS:永远不要在 name="submit" 或 id="submit" 的表单中调用任何内容

【讨论】:

    【解决方案5】:

    如果你可以使用jquery,你可以使用:

    event.preventDefault()
    

    喜欢:

    $("#formId").submit(function(event) {
    ...
      event.preventDefault();
    ...
    });
    

    http://api.jquery.com/event.preventDefault/

    【讨论】:

    • 他没有说他在使用 jQuery(而且很明显没有这样做)。请不要使用仅限 jQuery 的答案来回答 JavaScript 问题。
    • Topera 明确表示“如果你可以使用 jquery”。 Topera 的回答很好。
    • @T.J. Crowder 我确实使用 jQuery,这个答案很有帮助,我也看不出任何人会避免使用它的任何理由......
    • @IlyaD:如果您使用 jQuery,最好适当地标记问题。 (并使用 jQuery 进行连接!)我已经更新了我的答案以包含 jQuery 特定的东西。
    • @IlyaD:不。当您调用event.preventDefault(); 时,您将停止事件的默认操作。因此,不会提交表单。
    【解决方案6】:

    试试这个

    document.forms[formID].addEventListener('submit', function(event)
    {
         event.preventDefault();
         CheckedN = this.name;
        CorrectAnswer = questions.correctAns[CheckedN];
        UserAnswer = -1;
    
        for (var i=0; i < 4; i++) {
            if (this.answerN[i].checked === true) {
                UserAnswer = i;
            }
        }
    
        if (UserAnswer === -1) {alert("Please choose an answer");}
        else {
            if (UserAnswer === CorrectAnswer) {alert("You are correct!");}
            else {alert("You are wrong!");}
            }
    
    return false;
    
    }, false);
    

    或者,您可以尝试将validate() 更改为validate(event) 并在那里调用event.preventDefault();,但我不是100% 的。

    【讨论】:

    • 为什么要采用一个非常好的命名函数并使其匿名?让函数具有名称有助于您的工具帮助您(通过在调用堆栈中显示它们等)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    • 2012-01-29
    相关资源
    最近更新 更多