event.preventDefault();在 AJAX 中不起作用

event.preventDefault(); not working in ajax

本文关键字:AJAX 不起作用 preventDefault event      更新时间:2023-09-26

我正在注册表单上发出ajax调用,其中我正在检查用户输入的电子邮件ID是否已被使用。阿贾克斯函数:

<script>

$( "#becomesignup" ).submit(function( event ) {
        $.ajax({
            url : 'login', // Your Servlet mapping or JSP(not suggested)
            data : {"email":$("#becomeemail").val()},
            type : 'GET',
            dataType : 'html', // Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.
            success : function(response) {
                if(response == "true"){
                    $('#emailerrorbecome').slideDown();
                    $('#become-submit').prop('disabled', true);
                  event.preventDefault();
                }else{
                    $('#emailerrorbecome').slideUp();
                    $('#become-submit').prop('disabled', false);
                }
                 $('.black-screen').hide();
              },
              error : function(request, textStatus, errorThrown) {
                alert(errorThrown);
            }
        });
});
</script>

在上面的 ajax 函数中,如果响应为 true,则电子邮件 ID 已被使用,我需要显示错误div($('#emailerrorbecome').slideUp();)然后阻止提交表单。但即使是 event.preventDefault() 也无法正常工作,导致电子邮件 ID 再次注册。请帮我解决这个问题。蒂亚

您应该以编程方式提交表单,并始终阻止 jq 提交处理程序中的默认行为。例如,使用上下文并调用 DOM API 方法submit()

$("#becomesignup").submit(function(event) {
    event.preventDefault(); /* prevent form submiting here */
    $.ajax({
        context: this, /* setting context for ajax callbacks*/
        url: 'login', // Your Servlet mapping or JSP(not suggested)
        data: {
            "email": $("#becomeemail").val()
        },
        type: 'GET',
        dataType: 'html', // Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.
        success: function(response) {
            if (response == "true") {
                $('#emailerrorbecome').slideDown();
                $('#become-submit').prop('disabled', true);  
                $('.black-screen').hide(); /* hide it here */
            } else {
                $('#emailerrorbecome').slideUp();
                $('#become-submit').prop('disabled', false);
                this.submit(); /* 'this' refers to the FORM, and calling submit() DOM native method doesn't fire again jq handler */
            }
        },
        error: function(request, textStatus, errorThrown) {
            alert(errorThrown);
        }
    });
});

有关原因的解释,请参阅昆汀的答案

你打电话给preventDefault迟到了。

执行顺序如下:

  1. 事件处理程序触发
  2. 发送 HTTP 请求
  3. 事件处理程序完成
  4. 未调用阻止默认值,因此发生默认行为
  5. 收到 HTTP 响应
  6. 成功处理程序触发
  7. 防止默认称为...为时已晚,无法产生任何效果

在阻止默认行为之前,不能等待 HTTP 响应返回。

您要么需要始终阻止默认行为,然后在提交处理程序中使用JS有条件地重新提交表单,要么移动使用Ajax执行测试时的逻辑,以便它首先不依赖于表单提交事件(例如,在输入数据后立即运行它,并为表单可能在JS完成之前提交的可能性做好准备运行)。

您无法在

submit 函数返回很长时间后阻止submit。Ajax 结果发生得更晚。

您可以改为标记提交(例如,使用 sentinel 变量)并取消它,除非允许。然后从 Ajax 回调中的代码触发submit

例:

var allowSubmit = false;
$( "#becomesignup" ).submit(function( event ) {
    if (!allowSubmit){
        $.ajax({
            url : 'login', // Your Servlet mapping or JSP(not suggested)
            data : {"email":$("#becomeemail").val()},
            type : 'GET',
            dataType : 'html', // Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.
            success : function(response) {
                if(response == "true"){
                    $('#emailerrorbecome').slideDown();
                    $('#become-submit').prop('disabled', true);
                  // Enable next submit to proceed
                  allowSubmit = true;
                  // And trigger a submit
                  $( "#becomesignup" ).submit();
                }else{
                    $('#emailerrorbecome').slideUp();
                    $('#become-submit').prop('disabled', false);
                }
                 $('.black-screen').hide();
              },
              error : function(request, textStatus, errorThrown) {
                alert(errorThrown);
            }
        });
    }
    // return false does e.preventDefault(), and true allows it to proceed
    return allowSubmit;
});
您可以使用

return false而不是eventPreventDefault。我一直在使用 location.reload() 作为刷新页面以防止提交的肮脏黑客,但即使不刷新return false也能很好地工作,它不会提交表单。