HTML表单是如何触发提交的?

17

提前道歉,我无法提供任何实际的代码,因为该问题出现在当前私有页面中 :-/ 请耐心等待。

我有一个HTML表单,将一个(专有的)日历小部件附加到其中一个文本输入字段上。当用户切换到该字段时,日历会出现。在日历上有一些按钮(用于转到上一个/下一个月)。当用户点击其中一个按钮时,日历会相应地更新自身,但同时 - 表单提交!日历代码中没有任何东西会接触除了日历自身和与之关联的文本输入字段之外的任何内容,更不用说提交表单了! 我希望得到以下问题的任何线索:

1)在这种情况下,可能是什么样的内容提交了表单?

2)通常还有哪些方式可以提交表单,除了点击提交按钮或按Enter键之外?(特别是,普通的按钮是否会提交表单?在什么情况下?)

3)如果我无法解决此问题,则作为解决方法,是否有一种方法可以完全禁用提交表单(然后在提交键附加的事件处理程序中重新启用它)?

注意事项:除此之外,该日历的行为正常 - 对键事件和日期本身(不是按钮)的单击事件正常响应。我在Firefox和Chrome上尝试过,并得到了相同的行为。我尝试使用FireBug逐步跟踪单击事件处理程序,一切都看起来非常正常 - 但是当它完成时,表单被提交(并且页面重新加载)。该小部件使用jQuery 1.7.2。非常感谢您在理解和/或解决这个问题方面提供的任何帮助!


1
在日历按钮的onclick事件中,您需要调用e.preventDefault() - 大多数按钮将提交表单/页面,除非您明确阻止该默认行为。如果这不起作用,请尝试e.stopPropagation() - mpen
2
你无法创建一个能够展示问题的SSCCE吗? - Dave Newton
1
@ŠimeVidas:他说专有的;我猜是由他或他的公司制作的。 - mpen
1
@ŠimeVidas:在那个意义上可能是“public”,但我们可能不熟悉。但我想他自己可以回答这个问题 :) - mpen
@Tom 那么你在 OP 中排除的东西一定是不正确的,因为所有答案都涵盖了那些东西。虽然这没关系,但会让人误解。不过还好你已经解决了。 - Dave Newton
显示剩余10条评论
5个回答

34

很抱歉自己回答自己的问题,但是尽管我从答案和评论中学到了一些东西,但是没有一个答案是完整的!感谢所有参与的人!

所以:

1+2) 通过<button>元素定义的按钮会导致提交(就像它们设置了type="submit"一样,在某些浏览器中)如果想让按钮导致提交,则应使用<button type="button">或经典的<input type="button" />

3) (对我来说现在不必要,但它是问题的一部分。)有很多方法可以防止表单提交。其中三个方法是:

  • 处理onsubmit事件,在未设置标志时预防提交(通过return false; 或者 - 更好的选择! - 通过e.preventDefault(););在处理实际提交表单的事件时设置标志

  • 处理onsubmit事件,并在未触发事件的元素不是我们要提交的元素时像上面那样预防提交

  • 将表单操作设置为非操作,即action="#",并且具有实际提交表单的事件处理程序将操作设置为正确的地址


1
“return false” 是 jQuery 的一个特性。它会同时调用 e.preventDefault()e.stopPropagation()。回答自己的问题也没有问题;感谢分享你的发现。 - mpen
2
感谢您的评论,@Mark。return false;不是jQuery的东西。它也适用于纯JavaScript(也许它不是跨浏览器的?我不知道。我只是在Firefox上尝试了一下,至少可以防止默认行为)。我写下preventDefault()更可取,因为实际上return false;也会停止传播(至少在jQuery中是这样。我不确定纯JavaScript),这不一定是我们想要的。我们想要防止默认行为。 - Tom
很好知道,@Mark!所以,如果我理解正确的话,return false;作为防止默认行为的手段似乎是相当普遍的。jQuery的特殊之处在于它还停止了冒泡。 - Tom
是的,看起来是这样。我猜它确实阻止了跳转到那个链接,所以它防止了默认操作但没有冒泡。我也学到了东西 =) - mpen
这个答案让我找到了解决问题的方法——表单的提交导致了按钮内部的一个不必要的点击事件。该按钮没有 type="button" 属性,添加后问题得到了解决。 - pesho hristov

1

日历代码没有在某个地方调用submit()吗?

3) 如果我无法解决这个问题,作为解决方法,是否有一种方法可以完全禁用提交表单(然后在附加到提交键的事件处理程序中重新启用它)?

不幸的是,我不确定click处理程序在表单submit事件之前是否可靠被调用。

( function () {

  var prevent_submit = true;

  $( "form" ).on( 'submit', function ( event ) {

    if ( prevent_submit ) {

      event.preventDefault();

    }

  } );


  $( "input[type='submit']" ).on( 'click', function ( event ) {

    prevent_submit = false;

  } );

} )();

或者

$( "form" ).attr( { action : "#", method : "post" } );

$( "input[type='submit']" ).on( 'click', function ( event ) {

  event.target.form.action = "...";

} );

日历代码绝对没有在任何地方调用submit()。感谢您提供有关如何禁用提交的提示! - Tom
到现在为止,我已经明白了<button></button>按钮提交表单,而且必须使用<input type="button" /><button type="button"></button>... - Tom

1

日历可以通过使用jQuery或纯JavaScript调用表单的submit()方法来提交您的表单。

以下是一个示例,演示如何禁用表单提交,并仅在按下按钮时允许提交。

<form id="form">
    <input type="text" />
    <input type="button" name="submit-button" value="Submit"/>
</form>​
<script type="text/javascript">
    var form = document.getElementById('form'),
        button = form['submit-button'];
    form.onsubmit = function(e) {
        return !!form.getAttribute('data-allow-submit');
    };
    button.onclick = function() {
        form.setAttribute('data-allow-submit', 1);
        form.submit();
    };
</script>

演示


不想让日历提交表单 - 这就是整个问题所在!感谢您提供的示例,说明如何防止除提交按钮以外的其他来源提交表单! - Tom

0

检查一下闭合表单标签的位置。我曾经遇到过这个问题,最终发现是表单本身存在一些“权限”代码,阻止用户到达闭合标签,因为他没有适当的权限级别来提交它。实际上,这留下了一个开放的表单标签,然后响应同一页其他按钮的操作。


0
有时在文本字段上按回车键可能会触发表单提交。 在这里看看。 特别是如果这是表单中唯一的元素。控制后台提交的一种方法是将操作设置为空,并使用Javascript自己触发事件。

是的,我知道按回车键会提交表单。这就是为什么我问:“2)除了点击提交按钮或按回车键之外,通常有哪些东西可以提交表单?”感谢您关于禁用提交的提示。 - Tom
通常情况下,用户只需输入信息并点击提交按钮即可。当然,第三方开发者可以根据应用程序的需要设置Tab键、空格键或其他快捷键。如果您想控制行为,您将需要手动触发“submit()”。 - Visionary Software Solutions

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接