gpt4 book ai didi

javascript - 输入类型="submit",onclick处理程序调用this.form.submit(),并且不返回任何值

转载 作者:数据小太阳 更新时间:2023-10-29 05:23:27 27 4
gpt4 key购买 nike

编辑:在考虑回答问题之前,请仔细阅读问题的所有内容。我既不是在生产代码中使用内联事件处理程序的可取性,也不是在实现我所引用的文章所 promise 的结果的最佳方法。这是关于Javascript语义和浏览器实现细节的问题,而不是关于最佳编码实践的问题。

听起来像一场噩梦,对吗?

但是我发现一些online advice提倡这样做,以防止再次提交表单:

<input type="submit" 
onclick="this.disabled=true;
this.value='Sending, please wait...';
this.form.submit();" />

撇开对内联事件处理程序的弊端的任何讨论,我在这里看到的问题是:
  • 标签的类型是"submit",因此提交其包含形式是其默认行为;
  • onclick处理程序显式提交包含表单;
  • onclick处理程序不返回false以防止默认行为(请参见1)。

  • 凭直觉,我认为单击此项目将与本文所声称的完全相反-即,两次提交表单,一次是由于显式 submit()调用的结果,另一次是由于未抑制的默认行为 "submit"类型的控件。

    另一方面,我编写了一个小的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>

    那么,这两种浏览器实际上是在做“正确的”事情吗(其中“正确”是在一些我没有看到或没有足够仔细地阅读的文档中定义的),这意味着我对问题的分析是不完整的或错误的?

    还是我的分析是正确的-意味着观察到的单个提交是浏览器实现者采用特殊情况的逻辑来节省天真的编码者的结果?

    更新:

    为了尝试通过@sourcecode检验声明, form.submit()方法是表单上的某种“第二个提交按钮”,因此要遵循 17.13.2 of the HTML4 spec节中所述的规则,即只能有一个“成功”提交按钮,我在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
    }
    ?>

    在Firefox中,此代码生成单个错误日志条目:

    Got form submission at timestamp, tellme = 1



    这确实表明方法调用已以某种方式被控件的内在事件驱动的行为所取代。

    此外,如果在将 return false;的值设置为1之后添加了额外的 tellme(从而防止了click事件的传播,从而防止了控件的固有行为),则单个错误日志条目为:

    Got form submission at timestamp, tellme = 0



    表示在这种情况下,提交是调用 this.form.submit()的结果。

    另一方面,当我在Safari中尝试相同的两个变体时,每个变体给了我相同的单个错误日志条目:

    Got form submission at timestamp, tellme = 0



    因此,对于Safari而言,方法调用始终优先于事件驱动的提交-大概是因为它发生得更早。

    那是。只是。惊人的。 :-/

    进一步更新:我有机会在Windows NT 5.1的IE 8.0上对此进行测试。

    IE 8反射(reflect)了Safari的行为,即 form.submit()方法始终优先于偶数驱动的提交。

    尽管今天几乎没有关系,但我也意识到我在运行OS X 10.4.11的更古老的PowerPC iMac上安装了古老的IE 5.22。有趣的历史琐事是IE5的 与IE8的恰好相反:事件驱动的提交始终会取代 form.submit()方法-即使click事件在末尾被 return false;禁止传播 onclick处理程序! (不过,我还没有深入研究这是错误还是功能。我尚未-可能永远不会!-运行测试以确定它是在破坏事件抑制能力,还是试图做一些“聪明的事情”。 “。)

    尽管如此,无论不一致如何,两个IE都只提交一次。

    我的初步结论(到目前为止,实际上是非常坚定的)结论是,“提交”类型的控件与DOM form.submit()方法之间的确切关系还没有很好地定义,并且浏览器实现者在没有任何明确指导的情况下,通常会尽其所能(例如,参见 @Boris Zbarsky's answer)。

    至少在Firefox,Safari和IE的情况下,他们的实现者预见到事件和方法调用可能竞争提交同一表格的可能性,并采取了一些步骤(尽管有所不同-基本上是在色域上进行)以确保他们中只有一个会成功。

    (我仍然欢迎来自其他人的其他答案,这些人知道不同的浏览器内部知识足以发表评论,或者使用除我测试过的浏览器以外的其他浏览器加载了我的简单PHP脚本。)

    最佳答案

    Gecko(Firefox)当然会检测到多个提交,并在出现新提交时取消较旧的提交。请参阅http://hg.mozilla.org/mozilla-central/file/c4abfca219e5/content/html/content/src/nsHTMLFormElement.h中的mPendingSubmisson成员,以及http://hg.mozilla.org/mozilla-central/file/c4abfca219e5/content/html/content/src/nsHTMLFormElement.cpp中对其的处理(例如nsHTMLFormElement::SubmitnsHTMLFormElement::PostHandleEvent(后者是从提交控件的默认操作 Material 中调用的名称))。

    就规范说的而言,我尚不清楚规范是否一定是理智的,但它存在于http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#concept-form-submit中,并暗示两种提交都会发生,但是由于“导航”的内部细节,后者可能有效地取消了较早的提交。算法。我提交了https://www.w3.org/Bugs/Public/show_bug.cgi?id=20580来整理规范。

    关于javascript - 输入类型="submit",onclick处理程序调用this.form.submit(),并且不返回任何值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14179769/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com