javascript input type="submit",onclick handler调用this.form.submit(),没有返回值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14179769/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
input type="submit", onclick handler calls this.form.submit(), and returns no value
提问by Hephaestus
EDIT: Please read carefully all the way through the question before you consider answering it. I am notasking about the advisability of using an inline event handler in production code, nor am I asking about the best way to achieve the result promised by the article I reference. This is a question about Javascript semantics and browser implementation details, not about best coding practices.
编辑:在考虑回答问题之前,请仔细阅读整个问题。我不是在问在生产代码中使用内联事件处理程序的可取性,也不是在问实现我引用的文章所承诺的结果的最佳方法。这是一个关于 Javascript 语义和浏览器实现细节的问题,而不是关于最佳编码实践的问题。
Sounds like a nightmare, right?
听起来像是一场噩梦,对吧?
Yet I found some online advicethat advocates doing just such a thing to prevent double-submission of a form:
然而,我发现一些在线建议提倡做这样的事情来防止重复提交表格:
<input type="submit"
onclick="this.disabled=true;
this.value='Sending, please wait...';
this.form.submit();" />
Leaving aside any discussion of the evils of inline event handlers, the problems I see here are:
暂且不谈内联事件处理程序的弊端,我在这里看到的问题是:
- The type of the tag is
"submit"
, so submitting its containing form is its default behavior; - The
onclick
handler explicitlysubmits the containing form; - The
onclick
handler doesn't returnfalse
to prevent the default behavior (see 1).
- 标签的类型是
"submit"
,所以提交它的包含表单是它的默认行为; - 的
onclick
处理程序明确地提交含有表 - 该
onclick
处理器不返回false
,防止默认行为(参见图1)。
Intuitively, I would think that a click on this item would do exactly the oppositeof what the article claims -- i.e., submit the form twice, once as a result of the explicit submit()
call, and then once more as the unsuppressed default behavior of the "submit"
-typed control.
直觉上,我认为点击这个项目会做与文章声称的完全相反的事情——即,提交表单两次,一次是显式submit()
调用的结果,然后再一次作为不受抑制的默认行为"submit"
-类型控制。
On the other hand, I wrote a tiny PHP script (below) and tried it out with both Firefox and Safari (at the moment my only conveniently available browsers), and it only writes a single log entry per click on the button:
另一方面,我编写了一个很小的 PHP 脚本(如下),并在 Firefox 和 Safari(目前我唯一方便使用的浏览器)上进行了尝试,每次单击按钮时它只写入一个日志条目:
<html>
<head></head>
<body>
<?php
if (isset($_GET['action']) && $_GET['action'] == 'submit') {
$s = 'Got form submission at ' . time();
error_log($s);
echo $s;
}
else {
?>
<form action="http://localhost/~hephaestus/phptests/submittest.php?action=submit"
method="post">
<input type="submit"
onclick="this.disabled=true;
this.value='Sending, please wait...';
this.form.submit();" />
</form>
<?php
}
?>
</body>
</html>
So are these two browsers actually doing the "right" thing (where "right" is defined in some document that I either haven't seen or haven't read closely enough) -- meaning that my analysis of the problems is incomplete or wrong?
那么这两个浏览器是否真的在做“正确”的事情(其中“正确”是在我没有看过或没有足够仔细阅读的某些文档中定义的)——这意味着我对问题的分析不完整或错误?
Or, is my analysis correct -- meaning that the observed single submissions are the result of the browser implementers putting in special-case logic, to save naive coders from themselves?
或者,我的分析是否正确——这意味着观察到的单个提交是浏览器实现者放入特殊情况逻辑的结果,以从他们自己中拯救天真的编码者?
UPDATE:
更新:
In an effort to empirically test out the claim by @sourcecode that the form.submit()
method is some sort of "second submit button" on a form, and is thus subject to the rule stated in section 17.13.2 of the HTML4 specthat there can only be one "successful" submit button, I made a few additions to my PHP test script:
为了凭经验测试@sourcecode 的声明,即该form.submit()
方法是表单上的某种“第二个提交按钮”,因此受制于HTML4 规范第17.13.2节中规定的规则,即只能有一个“成功”的提交按钮,我对我的 PHP 测试脚本做了一些补充:
<?php
if (isset($_GET['action']) && $_GET['action'] == 'submit') {
$s = 'Got form submission at ' . time() . ', tellme = ' . $_POST['tellme'];
error_log($s);
echo $s;
}
else {
?>
<form action="http://localhost/~hephaestus/phptests/submittest.php?action=submit"
method="post">
<input type="hidden" id="tellme" name="tellme" value="0" />
<input type="submit"
onclick="this.disabled=true;
this.value='Sending, please wait...';
this.form.submit();
document.getElementById('tellme')=1;" />
</form>
<?php
}
?>
In Firefox, this code produces the single error-log entry:
在 Firefox 中,此代码生成单个错误日志条目:
Got form submission at timestamp, tellme = 1
在时间戳提交表单,告诉我 = 1
which doessuggest that the method-invocation is somehow being superseded by the intrinsic event-driven behavior of the control.
这确实表明方法调用以某种方式被控件的内在事件驱动行为所取代。
Furthermore, if I include an additional return false;
after setting the value of tellme
to 1 (thereby preventing the click event from propagating, and thus preventing the intrinsic behavior of the control), the single error-log entry is:
此外,如果我return false;
在将 的值设置tellme
为 1(从而阻止点击事件传播,从而阻止控件的内在行为)之后包含一个额外的内容,则单个错误日志条目是:
Got form submission at timestamp, tellme = 0
在时间戳提交表单,告诉我 = 0
meaning that in this case, the submission was the result of the invocation of this.form.submit()
.
这意味着在这种情况下,提交是调用的结果this.form.submit()
。
On the other hand, when I try the same two variations in Safari, eachof them gives me the same single error-log entry:
另一方面,当我在 Safari 中尝试相同的两个变体时,它们中的每一个都给了我相同的单个错误日志条目:
Got form submission at timestamp, tellme = 0
在时间戳提交表单,告诉我 = 0
So in the case of Safari, the method invocation always takes precedence over the event-driven submission -- presumably because it happens earlier.
所以在 Safari 中,方法调用总是优先于事件驱动提交——大概是因为它发生得更早。
That's. Just. Awesome. :-/
那是。只是。惊人的。:-/
Further update:I got a chance to test this on IE 8.0 on Windows NT 5.1.
进一步更新:我有机会在 Windows NT 5.1 上的 IE 8.0 上对此进行测试。
IE 8 mirrors the behavior of Safari, i.e., the form.submit()
method always takes precedence over the even-driven submit.
IE 8 反映了 Safari 的行为,即该form.submit()
方法始终优先于偶数驱动提交。
Although it's hardly relevant today, I also realized that I have an ancient IE 5.22 on an even more ancient PowerPC iMac running OS X 10.4.11. The interesting bit of historical trivia here is that IE5 works exactly oppositeto the way IE8 works: the event-driven submit always supersedes the form.submit()
method -- even when the click event has been inhibited from propagatingby a return false;
at the end of the onclick
handler! (I haven't delved into whether this is a bug or a feature, though. I haven't yet -- and may never! -- run a test to determine whether it's botching the event inhibition, or trying to do something "smart".)
虽然它在今天几乎不相关,但我也意识到我在运行 OS X 10.4.11 的更古老的 PowerPC iMac 上有一个古老的 IE 5.22。这里有趣的历史琐事是 IE5 的工作方式与 IE8 的工作方式完全相反:事件驱动的提交总是取代form.submit()
方法——即使单击事件已被处理程序return false;
末尾的a禁止传播onclick
!(不过,我还没有深入研究这是错误还是功能。我还没有 - 可能永远不会! - 运行测试以确定它是否在破坏事件抑制,或者试图做一些“聪明的事情” ”。)
Still, regardless of the inconsistencies, both of the IEs only do a single submission.
尽管如此,不管不一致,两个 IE 只做一次提交。
My tentative (well, by now, actually pretty firm) conclusion is that the precise relationship between a "submit"-typed control and the DOM form.submit()
method isn't well-defined, and that browser implementers, in the absence of any explicit guidance, generally do what they think best (see @Boris Zbarsky's answer, for example).
我的初步(好吧,到目前为止,实际上非常确定)结论是“提交”类型的控件和 DOMform.submit()
方法之间的确切关系没有明确定义,并且浏览器实现者在没有任何明确指导的情况下,通常做他们认为最好的事情(例如,请参阅@Boris Zbarsky 的回答)。
At least in the cases of Firefox, Safari and IE, their implementers foresaw the possibility that both an event and a method call might compete to submit the same form, and took steps (albeit different ones -- pretty much running the gamut) to ensure that only one of them would succeed.
至少在 Firefox、Safari 和 IE 的情况下,它们的实现者预见到事件和方法调用可能会竞争提交相同的表单的可能性,并采取措施(尽管不同 - 几乎运行色域)以确保只有其中一个会成功。
(I'd stillwelcome additional answers from folks who know different browser internals well enough to comment, or who've loaded my simple PHP script using browsers other than those I've tested.)
(我仍然欢迎那些非常了解不同浏览器内部结构以进行评论的人的其他答案,或者他们使用我测试过的浏览器以外的浏览器加载了我的简单 PHP 脚本。)
采纳答案by Boris Zbarsky
Gecko (Firefox) certainly detects multiple submissions and cancels older ones when new ones happen. See the mPendingSubmisson member in http://hg.mozilla.org/mozilla-central/file/c4abfca219e5/content/html/content/src/nsHTMLFormElement.hand the handling of it in http://hg.mozilla.org/mozilla-central/file/c4abfca219e5/content/html/content/src/nsHTMLFormElement.cpp(e.g. in nsHTMLFormElement::Submit
and nsHTMLFormElement::PostHandleEvent
(the latter being what gets called from the default action stuff for submit controls).
Gecko (Firefox) 肯定会检测到多个提交并在新提交发生时取消旧提交。看到mPendingSubmisson成员http://hg.mozilla.org/mozilla-central/file/c4abfca219e5/content/html/content/src/nsHTMLFormElement.h和它在处理http://hg.mozilla.org/ mozilla-central/file/c4abfca219e5/content/html/content/src/nsHTMLFormElement.cpp(例如在nsHTMLFormElement::Submit
和nsHTMLFormElement::PostHandleEvent
(后者是从提交控件的默认操作内容中调用的内容)。
In terms of what the spec says, it's not clear to me that the spec is necessarily sane, but it lives at http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#concept-form-submitand suggests that both submissions would happen, but the later might effectively cancel the earlier because of internal details of the "navigate" algorithm. I filed https://www.w3.org/Bugs/Public/show_bug.cgi?id=20580to sort the spec out.
就规范所说的内容而言,我不清楚规范是否一定是健全的,但它存在于http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of- control-and-forms.html#concept-form-submit并建议两种提交都会发生,但由于“导航”算法的内部细节,后者可能会有效地取消较早的提交。我提交了https://www.w3.org/Bugs/Public/show_bug.cgi?id=20580来整理规范。
回答by sourcecode
This is w3 org recommendation that:
这是 w3 org 的建议:
- If a form contains more than one submit button, only the activated submit button is successful.
Same is there with Submit Click and local JS form.Submit function , only the "submit" is activated not form.submit function. Because submit is primary and JS function is secondary..
you can learn more here link
- 如果一个表单包含多个提交按钮,则只有激活的提交按钮才能成功。
与 Submit Click 和本地 JS form.Submit 功能相同,只有“提交”被激活,而不是 form.submit 功能。因为提交是主要的,JS 功能是次要的..
你可以在这里了解更多链接
回答by mplungjan
NEVER execute script in onclick of a submit and for sure do NOT submit the form!!! Also if you disable the button the submit may be stopped!
永远不要在点击提交时执行脚本,并且一定不要提交表单!!!此外,如果您禁用该按钮,则提交可能会停止!
If the code in the article works it is by sheer luck and I imagine many browsers entering into a racing condition of having a disabled submit button and a submit event in the click of this disabled button.
如果文章中的代码有效,那完全是运气,我想许多浏览器都会进入一种竞争状态,即禁用提交按钮,单击此禁用按钮时会出现提交事件。
Here is an inline suggestion of something that aught to work in any browser
这是一个在任何浏览器中都可以工作的内联建议
<form action="..." method="post"
onsubmit="document.getElementById('subbut').innerHTML='Sending, please wait...'">
<span id="subbut"><input type="submit" /></span>
</form>
and the same unobtrusively:
同样不显眼:
window.addEventListener('load',function() {
document.getElementById('form1').addEventListener('submit', function(e) {
document.getElementById('subbut').innerHTML = 'Sending, please wait...';
})
})
<form action="..." method="post" id="form1">
<span id="subbut"><input type="submit" /></span>
</form>
回答by 0xDonut
I would imagine you would need to use the stopPropogation()
method. Ideally You would call a function from your onclick handler instead of making it all inline.. see this other stackoverflow answer for a thorough explanation
我想你会需要使用该stopPropogation()
方法。理想情况下,您将从您的 onclick 处理程序中调用一个函数,而不是将其全部内联。请参阅其他 stackoverflow 答案以获得详尽的解释