【问题标题】:jQuery - prevent default, then continue defaultjQuery - 防止默认,然后继续默认
【发布时间】:2012-12-31 18:14:02
【问题描述】:

我有一个表单,在提交时,我需要在提交表单之前进行一些额外的处理。我可以阻止默认的表单提交行为,然后进行额外的处理(它基本上是调用 Google Maps API 并向表单添加一些隐藏字段)——然后我需要提交表单。

有没有办法“防止默认”,然后在某个时候“继续默认”?

【问题讨论】:

标签: javascript jquery


【解决方案1】:

使用jQuery.one()

将处理程序附加到元素的事件。每个事件类型的每个元素最多执行一次处理程序

$('form').one('submit', function(e) {
    e.preventDefault();
    // do your things ...

    // and when you done:
    $(this).submit();
});

one 的使用也防止了无限循环,因为这个自定义的submit 事件在第一次提交后被分离。

【讨论】:

  • 再次点击后提交:(
  • 你可能会面临无限循环
  • 无限循环,函数应该是.on而不是.one
  • 为了防止死循环,首先解绑表单事件并提交。 $(this).unbind(); $(this).submit();
【解决方案2】:

当您将.submit() 事件绑定到表单,并在返回之前执行您想要执行的操作(true)时,这些操作会在实际提交之前发生。

例如:

$('form').submit(function(){
    alert('I do something before the actual submission');
    return true;
});

Simple example

jquery.com 上的另一个例子:http://api.jquery.com/submit/#entry-examples

【讨论】:

  • 你是说表单不会提交,直到“return true;”之前的所有代码语句执行了吗?
  • 是的,这正是submit() 函数的作用。
  • 这不是一个很好的例子,因为它是同步的。如果我需要做的是异步调用怎么办?所以情况是“点击提交->做异步的东西而不是'提交表单->在异步回调中填写表单中的一些字段->从回调提交表单”
  • 运行一些异步 jQuery 代码怎么样?!也可以吗?
  • 这对我很有用。我在提交之前用它来控制事情,如果事情不正确,我使用“return false”。我已经寻找这个解决方案一天了。非常感谢。
【解决方案3】:

我会这样做:

 $('#submiteButtonID').click(function(e){
     e.preventDefault();
     //do your stuff.
     $('#formId').submit();
 });

如果只需要提交表单,请先调用preventDefault,稍后使用submit()函数

【讨论】:

  • 不要在您的点击事件处理程序中涉及逻辑。将其委托给其他人负责。
  • 这假设肯定会点击一个按钮。如果用户只是从表单中点击“输入”按钮怎么办?这也将提交表单。因此,依靠点击提交按钮可能不是一个好主意。
  • 我只是举一个点击的例子......因为问题中没有提到相关代码......
  • 无论如何,您提供的 sn-p 只有在用户单击按钮时才有效。这不是表单的工作方式。还有其他建议吗?
  • 绑定点击,阻止其默认并触发提交按钮点击
【解决方案4】:

使用这种方式你会在你的 JS 上做一个无限循环。 为了做得更好,您可以使用以下方法

var on_submit_function = function(evt){
    evt.preventDefault(); //The form wouln't be submitted Yet.
    (...yourcode...)

    $(this).off('submit', on_submit_function); //It will remove this handle and will submit the form again if it's all ok.
    $(this).submit();
}

$('form').on('submit', on_submit_function); //Registering on submit.

希望对你有帮助! 谢谢!

【讨论】:

【解决方案5】:
      $('#myform').on('submit',function(event){
        // block form submit event
        event.preventDefault();

        // Do some stuff here
        ...

        // Continue the form submit
        event.currentTarget.submit();
  });

【讨论】:

  • TypeError: event.currentTarget.submit 不是函数
  • 就我而言,我不得不使用event.target.submit()
  • 没有一个(targetcurrentTarget)在工作。
  • 它应该是api.jquery.com/event.currentTarget。除非您的目标不是表单元素,因为只有表单才能submit
【解决方案6】:

恕我直言,这是最通用和最可靠的解决方案(如果您的操作是用户触发的,例如“用户点击按钮”):

  • 第一次调用处理程序时检查谁触发了它:
    • 如果用户触发它 - 做你的事情,然后再次触发它(如果你愿意) - 以编程方式
    • 否则 - 什么都不做(= “继续默认”)

例如,请注意这个添加“您确定吗?”的优雅解决方案。只需用属性装饰按钮即可弹出任何按钮。 如果用户不选择退出,我们将有条件地继续默认行为。

1。 让我们为每个想要“你确定”弹出警告文本的按钮添加:

<button class="btn btn-success-outline float-right" type="submit"  ays_text="You will lose any unsaved changes... Do you want to continue?"                >Do something dangerous</button>

2。 将处理程序附加到所有此类按钮:

$('button[ays_text]').click(function (e, from) {
    if (from == null) {  // user clicked it!
        var btn = $(this);
        e.preventDefault();
        if (confirm() == true) {
            btn.trigger('click', ['your-app-name-here-or-anything-that-is-not-null']);
        }
    }
    // otherwise - do nothing, ie continue default
});

就是这样。

【讨论】:

  • 很好的答案!我不知道您可以将额外的参数传递给 .trigger()
【解决方案7】:

jQuery 和上面@Joepreludian 答案的一个小变化:

需要牢记的要点:

  • .one(...) 而不是 .on(...) or .submit(...)
  • named 函数而不是 anonymous function,因为我们将在 callback 中引用它。

$('form#my-form').one('submit', function myFormSubmitCallback(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    var $this = $(this);
    if (allIsWell) {
        $this.submit(); // submit the form and it will not re-enter the callback because we have worked with .one(...)
    } else {
        $this.one('submit', myFormSubmitCallback); // lets get into the callback 'one' more time...
    }
});

您可以将下面sn-p中allIsWell变量的值更改为truefalse来测试功能:

$('form#my-form').one('submit', function myFormSubmitCallback(evt){
  evt.stopPropagation();
  evt.preventDefault();
  var $this = $(this);
  var allIsWell = $('#allIsWell').get(0).checked;
  if(allIsWell) {
    $this.submit();
  } else {
    $this.one('submit', myFormSubmitCallback);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="/" id="my-form">
  <input name="./fname" value="John" />
  <input name="./lname" value="Smith" />
  <input type="submit" value="Lets Do This!" />
  <br>
  <label>
    <input type="checkbox" value="true" id="allIsWell" />
    All Is Well
  </label>
</form>

祝你好运……

【讨论】:

    【解决方案8】:

    “没有提交循环的验证注入”:

    我只是想在 HTML5 验证之前检查 reCaptcha 和其他一些东西,所以我做了类似的事情(验证函数返回 true 或 false):

    $(document).ready(function(){
       var application_form = $('form#application-form');
    
       application_form.on('submit',function(e){
    
            if(application_form_extra_validation()===true){
               return true;
            }
    
            e.preventDefault();
    
       });
    });
    

    【讨论】:

      【解决方案9】:

      纯Javascript方式,防止默认后提交表单。

      这是因为HTMLFormElement.submit() never calls onSubmit()。所以我们依赖于那个奇怪的规范来提交表单,就好像它在这里没有自定义的 onsubmit 处理程序一样。

      var submitHandler = (event) => {
        event.preventDefault()
        console.log('You should only see this once')
        document.getElementById('formId').submit()
      }
      

      有关同步请求,请参阅 this fiddle


      等待异步请求完成同样简单:

      var submitHandler = (event) => {
        event.preventDefault()
        console.log('before')
        setTimeout(function() {
          console.log('done')
          document.getElementById('formId').submit()
        }, 1400);
        console.log('after')
      }
      

      您可以查看我的小提琴以获取异步请求的 example


      如果你对承诺感到失望:

      var submitHandler = (event) => {
        event.preventDefault()
        console.log('Before')
          new Promise((res, rej) => {
            setTimeout(function() {
              console.log('done')
              res()
            }, 1400);
          }).then(() => {
            document.getElementById('bob').submit()
          })
        console.log('After')
      }
      

      这里是that request

      【讨论】:

      • 在阻止默认并执行代码后,是否有一种通用方法可以在纯 javascript(而不是 jquery 或任何库、模块等)中执行特定触发事件的“默认操作”?呃,delayDefault?
      【解决方案10】:

      您可以使用e.preventDefault() 来停止当前操作。

      你做不到$("#form").submit();

       $('#form').submit(function (e)
      {
          return !!e.submit;
      });
      if(blabla...)
      {...
      }
      else
      {
          $('#form').submit(
          {
              submit: true
          });
      }
      

      【讨论】:

      • 这让我很困惑..这不是一直在转吗?