HTML文档中的name属性必须唯一吗?

68
我记得在规范中曾经读到过,id属性和name属性共享相同的命名空间并且必须唯一。因此,我一直尝试在我的应用程序中满足这个要求,甚至害怕将相同的idname分配给同一元素。
但是最近我开始使用ASP.NET MVC 3,它(像PHP一样)可以在多个输入控件上使用相同的name属性,在服务器端形成值的集合。我试图查找规范中相关的部分 - 但未能找到。也许我误解了什么,或者阅读了错误的文档?
那么它是什么呢?我想尽可能产生有效的HTML(在不同的应用程序中使用4.01和5)。我可以毫无顾虑地使用这个技巧吗?还是我会违反某些规定,最好坚持使用唯一值?
4个回答

66

name属性仅适用于<form>和表单元素(<input><textarea><select>)。它用于指定与提交表单时传递的名称/值对相关联的名称。

例如:

<input type="checkbox" name="foo" value="1" />

如果选中,将会提交foo=1。在DOM中,您可以通过将name指定为索引来从form.elements集合中引用表单元素。如果name不唯一,则该集合返回元素数组而不是元素。现代DOM支持按名称查找表单元素的方法如下:

 document.getElementsByName(nameValue)

注意:即使只找到一个元素,它始终返回一个数组。

id属性来自XML世界,是任何节点的唯一标识符,不仅仅是表单元素。与name属性不同,它适用于任何HTML节点。与name属性一样,它必须遵循有效的标识符规则。标识符应以字母开头,只能包含字母([a-zA-Z])、数字、连字符、下划线和冒号(注意ASP.NET用下划线开始保留的ID,因此它们将始终无法通过HTML/XML检查 - 实际上,某些代理会剥离它们)。要通过id查找任何HTML元素,请使用:

document.getElementById(idvalue)

这只返回一个DOM节点。


1
啊,我找到了! 看来我错过了上下文。 :) 实际上,还有一些其他元素适用于name属性,但它只是重复了id属性,并且实际上必须等于如果两者都被定义。幸运的是,这不适用于表单元素。 :) - Vilx-
需要注意的是,<a> 标签也使用名称属性作为锚文本。 - Jon Lawton
1
id和name在HTML5中可以包含除空格以外的任何字符,但必须至少有一个字符:http://www.w3.org/TR/html5/dom.html#the-id-attribute - westor

25

name属性不唯一。例如,它用于分组单选按钮。它表示特定表单属性的值。id必须是唯一的。


9

ID应该是唯一的,但您可以使用具有相同名称的多个表单元素。这是单选按钮的标准工作方式,因此您可以强制选择单选按钮组中的一个。


1

单选框输入组中的名称是否必须在表单之间唯一?

我了解到,名称不必唯一,因为单选框元素可以共享相同的名称,但没有人说不同表单中的单选框元素组是否会互相干扰。因此,我创建了下面的简单示例进行测试。在我的浏览器中,我可以选择下面示例中的6个单选框中的2个,并且有两个表单。因此,将它们放在单独的表单中将使它们隔离。

<form>
  <input type="radio" name="test" value="1">
  <input type="radio" name="test" value="2">
  <input type="radio" name="test" value="3">
</form>

<form>
  <input type="radio" name="test" value="a">
  <input type="radio" name="test" value="b">
  <input type="radio" name="test" value="c">
</form>

我也想知道新的<fieldset>元素是否会有同样的行为,但似乎不会。我猜这是有道理的,因为如果我发送表单,它需要格式化数据以适应名称冲突。在这里我只能选择6个单选按钮中的1个:

<form>
  <fieldset name="test1">
    <legend>test1</legend>
    <input type="radio" name="test" value="1">
    <input type="radio" name="test" value="2">
    <input type="radio" name="test" value="3">
  </fieldset>
  <fieldset name="test2">
    <legend>test2</legend>
    <input type="radio" name="test" value="a">
    <input type="radio" name="test" value="b">
    <input type="radio" name="test" value="c">
  </fieldset>
</form>

我不确定为什么有人想这样做,但是您也可以使用form=<form id>属性将每个元素与不同的表单关联起来。它似乎再次分离了单选框组。如下图所示:

<form id="a">
</form>

<form id="b">
</form>

<fieldset name="test1">
  <legend>test1</legend>
  <input form="a" type="radio" name="test" value="1">
  <input form="a" type="radio" name="test" value="2">
  <input form="a" type="radio" name="test" value="3">
</fieldset>
<fieldset name="test2">
  <legend>test2</legend>
  <input form="b" type="radio" name="test" value="a">
  <input form="b" type="radio" name="test" value="b">
  <input form="b" type="radio" name="test" value="c">
</fieldset>

我认为理想情况下,一个 fieldset 应该创建一些比仅仅视觉上更具有分组效果的东西,但是它没有实现。至少单选按钮可以通过表单进行分组。

补充说明:当您在一个表单内的两个或多个 fieldset 中使用相同名称时,表单数据会是什么样子?让我们看看。

我的猜想得到了证实。只有一个“test”参数,而 fieldset 对数据没有任何影响。尝试选择一个单选按钮并点击提交。

function examine(e){
  e.preventDefault()
  e.stopPropagation()
  var formData = new FormData(e.target)
  ,formProps = Object.fromEntries(formData)
  document.getElementById('out').innerText = JSON.stringify(formProps,null,2)
  return false;
}
document.getElementById('mainform').addEventListener('submit',examine)
<form id="mainform">
  <fieldset name="test1">
    <legend>test1</legend>
    <input type="radio" name="test" value="1">
    <input type="radio" name="test" value="2">
    <input type="radio" name="test" value="3">
  </fieldset>
  <fieldset name="test2">
    <legend>test2</legend>
    <input type="radio" name="test" value="a">
    <input type="radio" name="test" value="b">
    <input type="radio" name="test" value="c">
  </fieldset>
  <button type="submit">examine</button>
</form>
<pre id="out"></pre>


一个 fieldset 可能会创建一个视觉分组,但当表单被提交时请求会是什么样子呢?test 字段会取什么值?或者会有两个 test 字段发送到服务器吗?我认为这是你观察到的行为的主要原因。无论如何...不幸的是,这个答案并没有真正回答问题。 - Vilx-
@Vilx- 我知道这并没有回答原问题,但我想要补充细节。似乎没有人澄清你是否可以在两个不同的表单中使用相同的广播名,或者它们是否会相互干扰,因此我想创建一个演示来为自己和其他人澄清这一点。我认为这是对该页面上其他信息的有用补充。你的问题也很好。我在最后添加了另一个演示来回答你的问题,并显示只会创建一个字段。 - ADJenks
我还通过尝试实际提交表单进行了测试,似乎一个表单中的两个字段集仍然只有一个参数。这排除了创建FormData对象可能会破坏其中一个的可能性。 - ADJenks

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