【问题标题】:jQuery preventDefault() not working inside AJAX calljQuery preventDefault() 在 AJAX 调用中不起作用
【发布时间】:2014-03-31 14:05:46
【问题描述】:

所以,当用户输入电子邮件时,我正在检查电子邮件是否存在。

 $('form.recover-form#check-form').on('submit', function(e){

    var form    = $(this),
        input   = $('.check-recover-email'),
        span    = $('.recover-error'),
        email   = input.val();
    span.text('');
    e.preventDefault();
    $.ajax({
        url: 'ajax/check-email',
        async: 'false',
        cache: 'false',
        type: 'POST',
        data: {email: email},
        success: function(response) {
            if ( response == 'no' ) {
                span.text('email does not exist');
            } else if ( response == 'ok' ) {
                form.submit();
            }
        }
    });
});

php代码

if ( Input::isPost('email') )  {

    $email = Input::post('email');

    $check = $dbh->prepare(" SELECT * FROM users WHERE email = :email ");
    $check->execute(array( 'email' => $email ));

    echo ( $check->rowCount() == 1 ) ? 'ok' : 'no' ;

}

这样,只要我提交它提交的表单并且 AJAX 调用中的 e.PreventDefault() 不起作用。但是,如果我将e.PreventDefault() 放在 AJAX 调用之前,则表单不会提交,并且如果电子邮件不存在则会出现错误(这是我想要实现的)。

我不明白问题出在哪里,希望你能帮忙。

谢谢。

EIDT:这是更新后的代码

【问题讨论】:

  • 你不能这样做,因为 ajax 请求的异步特性......
  • 就像你做的那样把它放在请求之外..
  • e.preventDefault();不起作用,因为 ajax 是异步调用。请进行 ajax 同步或使用回调来实现此目标
  • 这里的事情流程有点混乱。实际发生的是,他们的用户提交了触发在后台运行的 ajax 请求的表单。当该请求返回时,您尝试取消提交事件,但为时已晚,它早就完成了。
  • 是的,我知道 preventDefault() 在 ajax 调用中不起作用,但是如果我在 ajax 之前将其向上移动,我该如何恢复提交并继续提交表单如果 ajax通话成功?

标签: php jquery ajax preventdefault


【解决方案1】:

问题是你在事件处理过程中没有调用preventDefault。相反,在事件处理期间,您启动 ajax 调用(这是异步的),然后让事件继续。 ajax 调用完成稍后,这已经太晚了,无法阻止事件的默认值——它已经发生了。

e.preventDefault() 直接移动到事件处理程序中,在ajax success 处理程序之外。

$('.recover-form').on('submit', function(e){
    var form    = $(this),
        input   = $('.check-recover-email'),
        span    = $('.recover-error'),
        email   = input.val();
    span.text('');
    e.preventDefault(); // <=================== Here
    $.ajax({
        url: 'ajax/check-email',
        async: 'false',
        cache: 'false',
        type: 'POST',
        data: form.serialize(),
        success: function(response){
            if ( response == 0 ) {
                // ============================ Not here, this would be too late
                span.text('email does not exist');
            }
        }
    });
});

在评论中,您说过:

是的,它适用于验证,但如果 ajax 返回肯定响应,我想提交表单。我只对 AJAX 进行检查,如果失败则停止提交,如果成功则继续提交。

您不能等待异步 ajax 调用的结果等待原始表单提交。相反,您要做的是取消原始表单提交,执行 ajax,然后如果结果正常,则使用原始 DOM form 元素上的 submit 方法重新提交表单。该方法不会重新触发 submit 事件处理程序。

示例:Live copy

<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<meta charset=utf-8 />
<title>Delaying form submit during ajax</title>
</head>
<body>
  <form action="http://www.google.com/search" method="GET">
    <input type="text" name="q" value="kittens">
    <input type="submit" value="Submit">
  </form>
  <script>
    (function() {
      $("form").submit(function(e) {
        var rawFormElement = this; // Remember the DOM element for the form

        // Stop form submission
        display("Got form submit event, simulating ajax");
        e.preventDefault();

        // Simulate ajax check of data
        setTimeout(function() {
          // (This is the 'success' callback for the ajax)
          display("Ajax call complete, pretending result is good and submitting");

          // All okay, go ahead and submit the form
          rawFormElement.submit(); // Doesn't trigger 'submit' handler
        }, 1500);
      });

      function display(msg) {
        $("<p>").html(String(msg)).appendTo(document.body);
      }
    })();
  </script>
</body>
</html>

【讨论】:

  • 是的,它适用于验证,但如果 ajax 返回肯定响应,我想提交表单。我只对 AJAX 进行检查,如果失败则停止提交,如果成功则继续提交。
  • @C.Ovidiu:要使用异步 ajax 请求来做到这一点,您必须停止表单提交,进行检查,如果检查正常,则改为以编程方式提交表单。 (表单的原始 DOM 元素上的 submit 函数在不触发 submit 处理程序的情况下提交它。)但是由于您在进行检查时无论如何都在序列化表单,为什么不在处理 ajax 调用时直接处理它?
  • 最后我只是这样做了,基本上需要发送恢复电子邮件,我想先检查电子邮件是否存在于数据库中。以编程方式提交对我不起作用,如果您查看@Arun 答案,他已经建议了。
  • @C.Ovidiu: :-) 同时,我添加了一个示例。 “以编程方式提交对我不起作用” 为什么不呢?
  • 不能告诉你原因,因为我不知道。 ajax 响应的检查工作和错误消息是否相应出现,但表单不提交。最后我在ajax调用中做了所有的事情
【解决方案2】:

由于 ajax 请求的异步特性,您无法阻止来自成功处理程序的默认操作。

默认情况下阻止表单提交,然后在成功处理程序中如果有效则再次调用提交。

$('.recover-form').on('submit', function (e) {
    var form = $(this),
        input = $('.check-recover-email'),
        span = $('.recover-error'),
        email = input.val();
    span.text('');
    //prevent the submit
    e.preventDefault();
    $.ajax({
        url: 'ajax/check-email',
        async: 'false',
        cache: 'false',
        type: 'POST',
        data: form.serialize(),
        success: function (response) {
            if (response == 0) {
                span.text('email does not exist');
            } else {
                //submit if valie
                form[0].submit()
            }
        }
    });
});

【讨论】:

  • 我试过了,但现在我总是收到错误消息,好像我输入的电子邮件总是错误的(事实并非如此)。只是一个问题,在 else 块中提交表单并不意味着它总是会遇到 e.preventDefault() 从而永远不会提交?
  • @C.Ovidiu 不,以这种方式提交不会触发事件处理程序。
  • @Karl-AndréGagnon 它也不起作用。现在,我总是收到错误消息,这意味着 if ( response == 0 ) if 始终为真。服务器端代码很好,我正在检查的电子邮件存在。
  • @C.Ovidiu 检查response的值
  • @ArunPJohny 我在那里有 75%。我检查了所有内容,如果电子邮件存在,则错误被删除,但表单保持静止,不提交。我将在 OP 中发布我更新的代码
【解决方案3】:

首先,您的选项不正确。 cacheasync 需要布尔值,而不是字符串。

async: false,
cache: false,

其次,不是在 ajax 请求之后提交表单,而是触发事件。试试这个吧。

form.get(0).submit();

它返回表单节点而不是 jquery 对象,允许您直接提交它而不是触发事件(否则您将有一个无限循环。)

在这种情况下,您实际上并不需要 async: falsecache: false

【讨论】:

    【解决方案4】:

    您需要执行以下操作:

    $('.recover-form').on('submit', function(e){
    
        e.preventDefault();
    
        var form    = $(this),
            input   = $('.check-recover-email'),
            span    = $('.recover-error'),
            email   = input.val();
        span.text('');
        $.ajax({
            url: 'ajax/check-email',
            async: 'false',
            cache: 'false',
            type: 'POST',
            data: form.serialize(),
            success: function(response){
                if ( response == 0 ) {
                    span.text('email does not exist');
                }
            }
        });
    });
    

    请注意我是如何将 e.preventDefault() 移到开头的。这是因为您在 ajax 请求响应时调用它,这可能会在表单提交后的 100 毫秒甚至几秒内发生

    【讨论】:

    • 这种方式有效,不提交,但是如果邮件存在的话我想提交表单,如果(response == 1)。
    【解决方案5】:

    这是因为为jQuery.ajax() 传递的成功函数是异步执行的,然后它将在事件处理函数完成后执行。

    你应该把e.preventDefault() out of ajax function。一切都会好起来的。

    【讨论】:

    • 是的,它适用于验证,但如果 ajax 响应返回肯定响应,我想提交表单。我只对 AJAX 进行检查,如果失败则停止提交,如果成功则继续提交。
    【解决方案6】:

    你可以试试这样的,

    <form name="myForm" onsubmit="return submitObj.validateAndSubmit();"> <!-- your form -->
    
    <!-- your AJAX -->
    
    var submitObj = {
      validateAndSubmit : function()
      {
        var form    = $('.recover-form'),
            input   = $('.check-recover-email'),
            span    = $('.recover-error'),
            email   = input.val();
        span.text('');
        $.ajax({
            url: 'ajax/check-email',
            async: 'false',
            cache: 'false',
            type: 'POST',
            data: form.serialize(),
            success: function(response){
                if ( response == 0 ) {
                   return false;
                }
                else{
                    return true;
                }
            }
        });     
    
      }
    
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-01
      • 2012-05-20
      • 1970-01-01
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      相关资源
      最近更新 更多