如何确定 HTML 表单上的默认提交按钮?

2022-08-30 00:48:03

如果表单已提交,但不是由任何特定按钮提交,例如

  • 通过按Enter
  • 在 JS 中使用HTMLFormElement.submit()

浏览器应该如何确定多个提交按钮中的哪一个(如果有)作为按下的按钮使用?

这在两个层面上都很重要:

  • 调用附加到提交按钮的事件处理程序onclick
  • 发送回 Web 服务器的数据

到目前为止,我的实验表明:

  • 按下时,Firefox,Opera和Safari使用表单中的第一个提交按钮Enter
  • 按下时,IE使用第一个提交按钮或根本不使用,具体取决于我无法弄清楚的条件Enter
  • 所有这些浏览器都不使用任何浏览器进行JS提交

标准是怎么说的?

如果它会有所帮助,这是我的测试代码(PHP只与我的测试方法相关,与我的问题本身无关)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
</head>

<body>

<h1>Get</h1>
<dl>
<?php foreach ($_GET as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>

<h1>Post</h1>
<dl>
<?php foreach ($_POST as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>

<form name="theForm" method="<?php echo isset($_GET['method']) ? $_GET['method'] : 'get'; ?>" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
    <input type="text" name="method" />
    <input type="submit" name="action" value="Button 1" onclick="alert('Button 1'); return true" />
    <input type="text" name="stuff" />
    <input type="submit" name="action" value="Button 2" onclick="alert('Button 2'); return true" />
    <input type="button" value="submit" onclick="document.theForm.submit();" />
</form>

</body></html>

答案 1

如果您通过 JavaScript(即,或任何等效项)提交表单,则不会将任何提交按钮视为成功,并且其任何值都不会包含在提交的数据中。(请注意,如果您使用提交表单,那么您引用的提交将被视为活动状态;这并不真正属于您的问题范围,因为这里的提交按钮是明确的,但我想我会为那些阅读第一部分并想知道如何通过JavaScript表单提交成功提交按钮的人包含它。当然,表单的提交处理程序仍然会以这种方式发射,而他们不会通过,所以这是另一壶鱼......formElement.submit()submitElement.click()form.submit()

如果在非文本区域字段中按 Enter 键提交表单,则实际上由用户代理决定它在此处想要的内容。规范没有说明在文本输入字段中使用键提交表单(如果您按 Tab 键到某个按钮并使用空格或其他方式激活它,则没有问题,因为该特定提交按钮被明确使用)。它所说的只是在激活提交按钮时必须提交表单。这甚至不是一个要求,例如,点击文本输入将提交表单。EnterEnter

我相信Internet Explorer选择在源代码中首先出现的提交按钮;我有一种感觉,Firefox和Opera选择了具有最低tabindex的按钮,如果没有定义其他按钮,则回退到第一个定义。关于提交是否具有非默认值属性 IIRC,也存在一些复杂情况。

需要注意的一点是,这里发生的事情没有明确的标准,这完全是浏览器的心血来潮 - 所以无论你在做什么,都要尽可能避免依赖任何特定的行为。如果你真的必须知道,你可能会发现各种浏览器版本的行为,但是当我一段时间调查这个问题时,有一些非常复杂的条件(当然,这些条件可能会随着新的浏览器版本而改变),我建议你尽可能避免它!


答案 2

HTML 4没有明确说明。HTML 5 指定第一个提交按钮必须是默认值

4.10.21.2 隐式提交

元素的默认按钮树形顺序中的第一个提交按钮,其窗体所有者是该元素。formform

如果用户代理支持让用户隐式提交表单(例如,在某些平台上,当文本控件聚焦时按“enter”键隐式提交表单),则对默认按钮具有激活行为且未禁用的表单执行此操作,必须导致用户代理在该默认按钮触发单击事件

如果你想在保持视觉秩序的同时影响哪一个是“第一”,那么你可以采取几种方法。

屏幕外无法对焦的按钮。

.hidden-default {
    position: absolute;
    left: -9999px;
}
<form>
  <input name="text">
  <button name="submit" value="wanted" class="hidden-default" tabindex="-1"></button>
  <button name="submit" value="not wanted">Not the default</button>
  <button name="submit" value="wanted">Looks like the default</button>
</form>

弹性盒订单:

.ordering {
    display: inline-flex;
}

.ordering button {
    order: 2;
}

.ordering button + button {
    order: 1;
}
<form>
  <input name="text">
  <div class="ordering">
    <button name="submit" value="wanted">First in document order</button>
    <button name="submit" value="not wanted">Second in document order</button>
  </div>
</form>