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

Javascript 如何在Safari提交表单之前执行JQuery,javascript,jquery,forms,safari,Javascript,Jquery,Forms,Safari,我遇到了一个问题,这似乎只是Safari中的一个问题。在css中,我有一个覆盖设置为display:none。当用户单击提交时,我希望覆盖显示,直到处理完成。我最初只是将它绑定到按钮的上('click'…函数在jquery中。除了在Safari中,这一切都很好。Safari希望在单击调用之前执行提交。因此,根据我发现的一些其他情况,我将所有这些都放在表单的提交事件上,而不是单击,并使用设置为0的超时对象。如下所示: $('#tcmi-shop-cart-checkout').submit(fun

我遇到了一个问题,这似乎只是Safari中的一个问题。在css中,我有一个覆盖设置为
display:none
。当用户单击提交时,我希望覆盖显示,直到处理完成。我最初只是将它绑定到按钮的
上('click'…
函数在jquery中。除了在Safari中,这一切都很好。Safari希望在单击调用之前执行提交。因此,根据我发现的一些其他情况,我将所有这些都放在表单的提交事件上,而不是单击,并使用设置为0的超时对象。如下所示:

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

这同样适用于除Safari之外的所有其他浏览器。Safari仍希望提交表单数据,并在执行此操作之前等待响应。如何使Safari在提交数据之前显示此覆盖?

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

代码:

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

我假设该按钮是一个“提交”按钮,并且通过单击该按钮触发的提交事件在您的javascript有机会显示覆盖之前触发。请尝试使用javascript提交表单,并使用
preventDefault
从按钮接收提交事件,如下所示:

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

您尝试过preventDefault()吗

如果您只是通过表单发布一些数据,您可以这样做(使用伪代码):

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

试试看

$("#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)
       })
    })
});

JSFIDLE

我最终不得不做一个疯狂的黑客来实现这一点。它基本上是上面提到的preventDefault()和其他一些东西的组合。因为如果我使用form.submit()的话,它就是一个Drupal表单它会使用我表单上的“后退”按钮,而不是实际的提交按钮,从而导致明显的问题。因此,我必须使用实际的提交按钮来触发。这基本上涉及到触发对按钮的第二次调用。第一次显示覆盖,然后再次调用提交,并实际触发提交。代码如下:

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

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


我有一个相同的问题,我用以下方法解决它:

$(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浏览器添加额外的检查。

我不确定它是否有效,但您应该尝试在提交表单时使用默认值,执行任务,然后手动提交。是否可以发布
html
css
?html是动态生成的,因为它来自我使用其自定义模块的表单API。@LoneWolfPR请参阅post.Nope。这不起作用。问题是Safari,由于某种原因,处理事件的方式与其他浏览器不同,并且希望在处理提交之前处理其他所有事情。setTimeout是一种有人说有效的黑客行为。它没有起作用。不幸的是,你的建议也没有起作用。不幸的是这也是有问题的。这是一个使用drupal表单API的多步骤表单。当我这样做时,它实际上会因为某种原因让我回到过去。这并不是说我无法以某种方式解决这个问题。我只是希望找到一种方法来解决Safari的问题,而不必重新编写许多其他代码。不幸的是,我不熟悉这一点表单API,但可能
preventDefault
比返回false更有效?这可能是一个比返回false更好的解决方案。我已经更新了解决方案,试一试。@LoneWolfPR请澄清您的问题并添加所有必要的信息,以便得到正确的答案。我不确定需要澄清什么。我我想我已经提供了所有必要的信息。这导致了我在上面的建议解决方案中提到的另一个问题。@LoneWolfPR,请澄清您的问题并添加所有必要的信息,以便获得正确的答案。我不确定需要澄清什么。我想我已经添加了所有必要的信息。
var someForm = $('.someform');
var someOverlay = $('.someOverlay');

someForm.on('submit', function(e) {
    e.preventDefault();
    someForm.off('submit');
    someOverlay.fadeIn('fast', function(){
        someForm.submit();
    });
});
$(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);
});