如何在Safari提交表单之前执行JQuery

时间:2015-03-05 18:42:47

标签: javascript jquery forms safari

我遇到了一个只在Safari中出现问题的问题。我在其css中设置了display:none的叠加层。当用户点击提交时,我希望显示叠加层直到处理完成。我最初只是将它绑定到jquery中按钮的on('click'...函数。除了在Safari中,这个工作得很好。 Safari希望在点击呼叫之前执行提交。所以,根据我发现的其他一些事情,我把它全部放在表单的提交事件而不是点击,并使用设置为0的超时对象。像这样:

$('#tcmi-shop-cart-checkout').submit(function(){
    var showOverlay = function(){$('#processing-overlay').css('display','block')};
     setTimeout(showOverlay,0);
});

这再次适用于除Safari之外的所有其他浏览器。 Safari仍然希望提交表单数据并在执行之前等待响应。如何在提交数据之前让Safari显示此叠加层?

7 个答案:

答案 0 :(得分:2)

您是否尝试过preventDefault()?

如果您只是通过表单发布一些数据,您可以执行以下操作(使用伪代码):

#form.submit() {
  preventDefault()
  setOverlay(true)
  POST()
    .then(setOverlay(false))
}

基本上,您希望阻止默认表单提交,在之后显示叠加层,然后使用ajax提交表单数据。您可以在完成后访问回调函数,并且可以在那里关闭覆盖。

答案 1 :(得分:1)

我假设该按钮是一个“提交”按钮,点击它后触发的提交事件在您的javascript有机会显示叠加层之前触发。尝试使用javascript提交表单,然后使用preventDefault从按钮中获取提交事件,如下所示:

$(function() {
    $('#submitButton').click(function(e) {
        $('#processing-overlay').css('display', 'block');
        $('#tcmi-shop-cart-checkout').submit();
        e.preventDefault();
    });             
});

答案 2 :(得分:1)

尝试

$("#tcmi-shop-cart-checkout").on("click", function(e) {
   e.preventDefault();
   e.stopPropagation();
    var el = $(this), elem = $("#processing-overlay");
    var settings = {};
    settings.url = el.attr("action");
    settings.type = el.attr("method");
    settings.context = elem;
    settings.data = el.serialize();

   elem.toggle(function() {
       $.ajax(settings)
       .then(function success(data, textStatus, jqxhr) {
         console.log(data);
         $(this).toggle()
       }, function error(jqxhr, textStatus, errorThrown) {
         console.log(textStatus, errorThrown)
       })
    })
});

jsfiddle http://jsfiddle.net/bmLkauzp/

答案 3 :(得分:0)

删除setTimeout,它应该可以正常工作。 在调用setTimeout时,您将函数推送到事件队列并释放线程,并且表单提交正在进行。

在代码中:

$('#tcmi-shop-cart-checkout').submit(function(){
    $('#processing-overlay').css('display','block');
});

答案 4 :(得分:0)

我不得不做一个疯狂的黑客来完成这项工作。它基本上是如上所述的preventDefault()和其他一些东西的组合。因为如果我使用form.submit()它是一个Drupal形式,它会使用' back'按钮我在我的表单上而不是实际的提交导致一个明显的问题。所以我不得不使用实际的提交按钮来执行触发器。这主要涉及触发按钮的第二次调用。第一次显示叠加层然后再次调用提交并实际触发提交。这是代码:

        var submitOpen = true;
        $('#edit-submit-order').on('click',function(e){
          if (submitOpen) {
               e.preventDefault();
               $('#processing-overlay').css('display','block');
               submitOpen = false;
               setTimeout(function(){$('#edit-submit-order').trigger('click')},5);
          } else {
               submitOpen = true
          }
        });

答案 5 :(得分:0)

这对我有用。这不是“干净”,但它有效:)

var someForm = $('.someform');
var someOverlay = $('.someOverlay');

someForm.on('submit', function(e) {
    e.preventDefault();
    someForm.off('submit');
    someOverlay.fadeIn('fast', function(){
        someForm.submit();
    });
});

答案 6 :(得分:0)

我有同样的问题,我用以下方法解决:

$(document).on("click", "input[type=\"submit\"]", function (e) {
    e.preventDefault();
    var $form = $(this).closest("form"),

    // Do whatever you want

    setTimeout(function () {
        $form.unbind('submit').submit();
    }, 200);
});

如果需要,您可以为safari浏览器添加额外的检查。