如果提交了表单,但不是通过任何特定的按钮,例如
按Enter键
使用JS中的HTMLFormElement.submit()
浏览器应该如何确定多个提交按钮(如果有的话)中的哪一个作为按下的按钮呢?
这在两个层面上很重要:
调用附加到提交按钮的onclick事件处理程序
数据发送回web服务器
到目前为止,我的实验表明:
当按Enter键时,Firefox、Opera和Safari使用表单中的第一个提交按钮
当按Enter键时,IE要么使用第一个提交按钮,要么根本不使用,这取决于我还没能弄清楚的条件
所有这些浏览器都不使用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>
If you submit the form via JavaScript (i.e., formElement.submit() or anything equivalent), then none of the submit buttons are considered successful and none of their values are included in the submitted data. (Note that if you submit the form by using submitElement.click() then the submit that you had a reference to is considered active; this doesn't really fall under the remit of your question since here the submit button is unambiguous but I thought I'd include it for people who read the first part and wonder how to make a submit button successful via JavaScript form submission. Of course, the form's onsubmit handlers will still fire this way whereas they wouldn't via form.submit() so that's another kettle of fish...)
If the form is submitted by hitting Enter while in a non-textarea field, then it's actually down to the user agent to decide what it wants here. The specifications don't say anything about submitting a form using the Enter key while in a text entry field (if you tab to a button and activate it using space or whatever, then there's no problem as that specific submit button is unambiguously used). All it says is that a form must be submitted when a submit button is activated. It's not even a requirement that hitting Enter in e.g. a text input will submit the form.
我相信Internet Explorer会选择在源代码中首先出现的提交按钮;我有一种感觉,Firefox和Opera会选择标签索引最低的按钮,如果没有其他定义,就会退回到第一个定义的按钮。关于提交是否具有非默认值属性IIRC,也存在一些复杂性。
The point to take away is that there is no defined standard for what happens here and it's entirely at the whim of the browser - so as far as possible in whatever you're doing, try to avoid relying on any particular behaviour. If you really must know, you can probably find out the behaviour of the various browser versions, but when I investigated this a while back there were some quite convoluted conditions (which of course are subject to change with new browser versions) and I'd advise you to avoid it if possible!
奇怪的是,第一个按钮进入总是第一个按钮,无论是否可见,例如使用jQuery的show/hide()。添加属性。attr('disabled', 'disabled')可以完全阻止接收输入提交按钮。这是一个问题,例如在调整记录对话框中的插入/编辑+删除按钮可见性时。我发现它不那么hackish和简单的将编辑放在插入前面:
<button type="submit" name="action" value="update">Update</button>
<button type="submit" name="action" value="insert">Insert</button>
<button type="submit" name="action" value="delete">Delete</button>
并使用JavaScript代码:
$("#formId button[type='submit'][name='action'][value!='insert']").hide().attr('disabled', 'disabled');
$("#formId button[type='submit'][name='action'][value='insert']").show().removeAttr('disabled');
HTML 4并没有将其显式化。HTML 5规定第一个提交按钮必须是默认的:
4.10.21.2隐式提交
表单元素的默认按钮是按树顺序排列的第一个提交按钮,其表单所有者就是该表单元素。
如果用户代理支持让用户隐式提交表单
(例如,在某些平台上,在输入文本时按下“enter”键
控件隐式地提交表单),然后为
表单,其默认按钮具有激活行为,但没有
禁用时,必须导致用户代理在此触发单击事件
默认按钮。
如果你想在保持视觉顺序的同时影响哪个是“第一个”,那么你可以采取一些方法。
一个屏幕外、无法对焦的按钮。
.hidden-default {
位置:绝对的;
左:-9999 px;
}
< >形式
<输入名称= " text " >
<button name="submit" value="wanted" class="hidden-default" tabindex="-1"></button>
<button name="submit" value="not wanted">不是默认值
<button name="submit" value="wanted">看起来像默认的</button>
> < /形式
Flexbox顺序:
.ordering {
显示:inline-flex;
}
. ordered按钮{
秩序:2;
}
.订购按钮+按钮{
顺序:1;
}
< >形式
<输入名称= " text " >
< div class = "排序" >
<button name="submit" value="wanted">文件顺序第一个</button>
<button name="submit" value="not wanted">在文档顺序中的第2位</button> . </button> . <button name="submit" value="not wanted
< / div >
> < /形式
我纠结于同样的问题,因为我在表单中间有一个提交按钮,可以重定向提交到另一个页面,就像这样:
<button type="submit" onclick="this.form.action = '#another_page'">More</button>
当用户按下Enter键时,单击的是这个按钮,而不是另一个提交按钮。
所以我做了一些基本的测试,创建了一个带有多个提交按钮和不同可见性选项的表单,并创建了一个onclick事件来提醒哪个按钮被单击:https://jsfiddle.net/aqfy51om/1/
我用于测试的浏览器和操作系统:
窗户
谷歌Chrome 43(来谷歌搜索:D)
Mozilla Firefox 38
Internet Explorer 11
Opera 30.0
OS X
谷歌Chrome 43
Safari 7.1.6
尽管应用了可见性选项,但大多数浏览器都点击了第一个按钮,除了ie和Safari会单击第三个按钮,这是一个“隐藏”容器中的“可见”按钮:
<div style="width: 0; height: 0; overflow: hidden;">
<button type="submit" class="btn btn-default" onclick="alert('Hidden submit button #3 was clicked');">Hidden submit button #3</button>
</div>
所以我的建议,也就是我自己的建议是:
如果你的表单有多个不同含义的提交按钮,那么在表单的开头包含一个默认动作的提交按钮,它可以是:
完全可见
用style="width: 0;高度:0;溢出:隐藏。”
另一种选择可能是偏移按钮(仍然在from的开头)style="position: absolute;左:-9999 px;顶部:-9999px;",刚刚尝试在Internet Explorer -工作,但我不知道它还能搞砸什么,例如打印..
现在可以使用Flexbox解决这个问题:
HTML
<form>
<h1>My Form</h1>
<label for="text">Input:</label>
<input type="text" name="text" id="text"/>
<!-- Put the elements in reverse order -->
<div class="form-actions">
<button>Ok</button> <!-- Our default action is first -->
<button>Cancel</button>
</div>
</form>
CSS
.form-actions {
display: flex;
flex-direction: row-reverse; /* Reverse the elements inside */
}
解释
使用Flexbox,我们可以通过使用CSS规则:flex-direction: row-reverse来反转使用display: flex的容器中的元素顺序。这不需要CSS或隐藏元素。对于不支持Flexbox的旧浏览器,他们仍然得到一个可行的解决方案,但元素不会被反转。
Demo
http://codepen.io/Godwin/pen/rLVKjm