jQuery preventDefault()在AJAX调用中不起作用

时间:2014-03-31 14:05:47

标签: php jquery ajax preventdefault

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

 $('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()就无法正常工作。但是,如果我在AJAX调用之前放置e.PreventDefault(),则表单不会提交,如果电子邮件不存在则会出现错误(这是我想要实现的)。

我无法理解问题所在,希望你能提供帮助。

谢谢。

EIDT:这是更新后的代码

6 个答案:

答案 0 :(得分:12)

问题是在处理事件期间不要调用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 submit元素上的form方法重新提交表单。该方法不会重新触发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>

答案 1 :(得分:3)

由于其异步性,您无法阻止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()
            }
        }
    });
});

答案 2 :(得分:3)

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

async: false,
cache: false,

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

form.get(0).submit();

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

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

答案 3 :(得分:1)

您需要执行以下操作:

$('.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毫秒甚至几秒内发生

答案 4 :(得分:0)

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

您应该将e.preventDefault() 放在ajax函数之外。一切都会奏效。

答案 5 :(得分:0)

最好你可以尝试这样的事情,

<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;
            }
        }
    });     

  }

};